home *** CD-ROM | disk | FTP | other *** search
/ Black Box 4 / BlackBox.cdr / os2 / maze32.arj / 3DMAZE.C next >
Encoding:
C/C++ Source or Header  |  1992-06-25  |  73.5 KB  |  1,982 lines

  1. #include <stdio.h>
  2. #define INCL_WIN
  3. #define INCL_GPI
  4. #define INCL_PM
  5. #define INCL_DOS
  6. #include <os2.h>
  7. #include <stdlib.h>
  8. #include <malloc.h>
  9. #include <math.h>
  10. #include "3dmaze.h"
  11.  
  12. #define ERROR_COLOR           CLR_RED
  13. #define RESOLUTION             4
  14. #define NUM_COLORS            16
  15. #define PIXELS_PER_ROOM       30
  16. #define TWICE_PIXELS_PER_ROOM 60      /* 2*PIXELS_PER_ROOM */
  17. #define WM_PLOT_DONE          WM_USER
  18.  
  19. /* screen constants */
  20. #define WIDTH_OF_SCREEN        8.0
  21. #define HEIGHT_OF_SCREEN       6.0 /* same units as WIDTH_OF_SCREEN */
  22.  
  23. typedef struct
  24.           {
  25.             unsigned char red;
  26.             unsigned char green;
  27.             unsigned char blue;
  28.           } rgb_rec;
  29.  
  30. typedef struct stack_rec_record
  31.           {
  32.             char          index_1;
  33.             char          index_2;
  34.           } stack_rec;
  35.  
  36. typedef struct
  37.           {
  38.             double x;
  39.             double y;
  40.             double z;
  41.           } vertex_rec;
  42.  
  43. static void      adjust_perspective(int,int,float *,float *,
  44.                   float *,double,double,double,double,double);
  45.        MRESULT EXPENTRY ClientWndProc(HWND,ULONG,MPARAM,MPARAM);
  46. static void      DestroyMaze(float **,float **,float **,
  47.                   int **,int **,unsigned char **,
  48.                   unsigned char **,stack_rec **);
  49. static void      evaluate_and_transform(double,double,double,double,int,int,
  50.                   double,double,float *,float *,float *,double *,double *,
  51.                   double *,double *,double *,vertex_rec *,int *,int *,
  52.                   unsigned char *);
  53. static double    f(double,double);
  54. static void      generate_maze(void);
  55. static void      hash(int *,int *,int *,int *,int *,int *,int *,int *);
  56. static void      increment(int *,int *,int *,int *,int *,int *,int *,int *);
  57.        MRESULT EXPENTRY HelpProc(HWND,ULONG,MPARAM,MPARAM);
  58.        int       main(void);
  59. static int       memory_allocated(long,float **,float **,
  60.                   float **,int **,int **,unsigned char **,
  61.                    unsigned char **,int,stack_rec **);
  62. static int       num_rooms_in_solution(void);
  63.    VOID APIENTRY plot(ULONG);
  64. static void      shade(int,int,float *,float *,float *,
  65.                   unsigned char *,vertex_rec *);
  66.    VOID APIENTRY SizeMaze(ULONG);
  67. static void      sort_back_to_front(long,float *,int *,int *);
  68.  
  69.  
  70. static double        aspect_ratio;
  71. static unsigned char *base_z;
  72. static unsigned char *color;
  73. static int           delta_x [4] [24];
  74. static int           delta_y [4] [24];
  75.        HPS           hPS;
  76. static short         horizontal_scroll_position;
  77. static HWND          hwndHscroll;
  78. static HWND          hwndVscroll;
  79. static int           iFatalError;
  80. static int           iMaxX;
  81. static int           iMaxY;
  82. static vertex_rec    light;
  83. static int           max_x;
  84. static int           max_x_less_1;
  85. static int           max_x_plus_1;
  86. static int           max_y;
  87. static int           max_y_less_1;
  88. static int           max_y_plus_1;
  89. static int           num_columns;
  90. static long          num_primes;
  91. static int           num_rooms_in_maze;
  92. static int           num_rows;
  93. static int           num_x_divisions;
  94. static int           num_y_divisions;
  95. static char          **page;
  96.        HEV           plot_active;
  97. static int           plot_command;
  98.        HWND          plot_hwnd;
  99. static int           plot_kill;
  100. static ULONG         plot_post_count;
  101.        TID           plot_thread_id;
  102. static ULONG         plotting;
  103. static int           r_n [8];
  104. static int           r_n_seed [7];
  105. static int           resized;
  106. static int           response;
  107. static double        rotation;
  108.        HEV           SizeMaze_active;
  109. static int           SizeMaze_kill;
  110. static ULONG         SizeMaze_post_count;
  111.        TID           SizeMaze_thread_id;
  112. static ULONG         sizing;
  113. static int           solve_draw_or_clear;
  114. static stack_rec     *stack;
  115. static int           tem_int;
  116. static double        tilt;
  117. static short         vertical_scroll_position;
  118. static int           *x_division_index;
  119. static double        x_max;
  120. static int           x_maze;
  121. static double        x_min;
  122. static int           x_next;
  123. static float         *x_prime;
  124. static double        x_prime_max;
  125. static int           x_wall;
  126. static int           *y_division_index;
  127. static double        y_max;
  128. static int           y_maze;
  129. static double        y_min;
  130. static int           y_next;
  131. static float         *y_prime;
  132. static double        y_prime_max;
  133. static double        y_prime_min;
  134. static int           y_wall;
  135. static float         *z_prime;
  136. static double        z_prime_max;
  137. static double        z_prime_min;
  138.  
  139. int main(void)
  140.   {
  141.     ULONG       ctldata;
  142.     HAB         hAB;
  143.     HMQ         hmq;
  144.     HWND        hwndClient;
  145.     HWND        hwndFrame;
  146.     QMSG        qmsg;
  147.     static CHAR szClientClass [] = "3D Maze";
  148.  
  149.     DosCreateEventSem((PSZ) NULL,(PHEV) &plot_active,(ULONG) 0,(BOOL32) 1);
  150.     DosCreateEventSem((PSZ) NULL,(PHEV) &SizeMaze_active,(ULONG) 0,(BOOL32) 1);
  151.     hAB=WinInitialize((ULONG) 0);
  152.     hmq=WinCreateMsgQueue(hAB,0l);
  153.     WinRegisterClass(hAB,(PSZ) szClientClass,(PFNWP) ClientWndProc,
  154.      (ULONG) CS_SIZEREDRAW,(ULONG) 0);
  155.     ctldata=(FCF_STANDARD | FCF_HORZSCROLL | FCF_VERTSCROLL);
  156.     hwndFrame=WinCreateStdWindow((HWND) HWND_DESKTOP,(ULONG) WS_VISIBLE,
  157.      &ctldata,(PSZ) szClientClass,(PSZ) NULL,(ULONG) 0,(HMODULE) NULL,
  158.      (ULONG) ID_MAINMENU,(PHWND) &hwndClient);
  159.     WinShowWindow((HWND) hwndFrame,(BOOL) TRUE);
  160.     while (WinGetMsg((HAB) hAB,(PQMSG) &qmsg,(HWND) NULL,(ULONG) 0,(ULONG) 0))
  161.      WinDispatchMsg((HAB) hAB,(PQMSG) &qmsg);
  162.     WinDestroyWindow((HWND) hwndFrame);
  163.     WinDestroyMsgQueue((HMQ) hmq);
  164.     WinTerminate((HAB) hAB);
  165.     return(0);
  166.   }
  167.  
  168. MRESULT EXPENTRY ClientWndProc(HWND hwnd,ULONG msg,MPARAM mp1,MPARAM mp2)
  169.   {
  170.     DATETIME dateSeed;
  171.     HWND     hwndMenu;
  172.  
  173.     switch (msg)
  174.       {
  175.         case WM_CREATE:
  176.           iFatalError=FALSE;
  177.           DosGetDateTime(&dateSeed);
  178.           r_n_seed[0]=dateSeed.year%10;
  179.           r_n_seed[1]=dateSeed.month%10;
  180.           r_n_seed[2]=dateSeed.day%10;
  181.           r_n_seed[3]=dateSeed.hours%10;
  182.           r_n_seed[4]=dateSeed.minutes%10;
  183.           r_n_seed[5]=dateSeed.seconds%10;
  184.           r_n_seed[6]=dateSeed.hundredths%10;
  185.           hwndHscroll=WinWindowFromID(WinQueryWindow(hwnd,QW_PARENT),
  186.            FID_HORZSCROLL);
  187.           WinSendMsg(hwndHscroll,SBM_SETSCROLLBAR,MPFROM2SHORT(0,0),
  188.            MPFROM2SHORT(0,360));
  189.           horizontal_scroll_position=0;
  190.           rotation=(double) (((short) 180)-horizontal_scroll_position);
  191.           hwndVscroll=WinWindowFromID(WinQueryWindow(hwnd,QW_PARENT),
  192.            FID_VERTSCROLL);
  193.           WinSendMsg(hwndVscroll,SBM_SETSCROLLBAR,MPFROM2SHORT(60,0),
  194.            MPFROM2SHORT(0,90));
  195.           vertical_scroll_position=60;
  196.           tilt=(double) (((short) 90)-vertical_scroll_position);
  197.           solve_draw_or_clear=(int) 'D';
  198.           iMaxX=0;
  199.           iMaxY=0;
  200.           resized=FALSE;
  201.           plot_command=FALSE;
  202.           aspect_ratio=(HEIGHT_OF_SCREEN/WIDTH_OF_SCREEN)
  203.            /(((double) WinQuerySysValue(HWND_DESKTOP,SV_CYSCREEN))
  204.            /((double) WinQuerySysValue(HWND_DESKTOP,SV_CXSCREEN)));
  205.           color=(unsigned char *) NULL;
  206.           base_z=(unsigned char *) NULL;
  207.           x_division_index=(int *) NULL;
  208.           x_prime=(float *) NULL;
  209.           y_division_index=(int *) NULL;
  210.           y_prime=(float *) NULL;
  211.           z_prime=(float *) NULL;
  212.           page=(char **) NULL;
  213.           stack=(stack_rec *) NULL;
  214.           break;
  215.         case WM_HSCROLL:
  216.           switch (SHORT2FROMMP(mp2))
  217.             {
  218.               case SB_LINELEFT:
  219.                 horizontal_scroll_position--;
  220.                 break;
  221.               case SB_LINERIGHT:
  222.                 horizontal_scroll_position++;
  223.                 break;
  224.               case SB_PAGELEFT:
  225.                 horizontal_scroll_position-=10;
  226.                 break;
  227.               case SB_PAGERIGHT:
  228.                 horizontal_scroll_position+=10;
  229.                 break;
  230.               case SB_SLIDERPOSITION:
  231.                 horizontal_scroll_position=SHORT1FROMMP(mp2);
  232.               case SB_ENDSCROLL:
  233.                 plot_command=TRUE;
  234.                 DosQueryEventSem((HEV) plot_active,&plotting);
  235.                 if (plotting == (ULONG) 0)
  236.                   plot_kill=TRUE;
  237.                 DosQueryEventSem((HEV) SizeMaze_active,&sizing);
  238.                 if (sizing == (ULONG) 0)
  239.                   {
  240.                     SizeMaze_kill=TRUE;
  241.                     DosWaitEventSem((HEV) SizeMaze_active,
  242.                      (ULONG) SEM_INDEFINITE_WAIT);
  243.                   }
  244.                 if (plot_kill)
  245.                   {
  246.                     DosWaitEventSem((HEV) plot_active,
  247.                      (ULONG) SEM_INDEFINITE_WAIT);
  248.                     WinEndPaint(hPS);
  249.                   }
  250.                 rotation=(double) (((short) 180)-horizontal_scroll_position);
  251.                 if ((iMaxX >= TWICE_PIXELS_PER_ROOM)
  252.                 &&  (iMaxY >= TWICE_PIXELS_PER_ROOM))
  253.                   {
  254.                     DosResetEventSem((HEV) SizeMaze_active,
  255.                      &SizeMaze_post_count);
  256.                     SizeMaze_kill=FALSE;
  257.                     DosCreateThread(&SizeMaze_thread_id,SizeMaze,(ULONG) 0,
  258.                      (ULONG) 0,16384);
  259.                   }
  260.                 switch (solve_draw_or_clear)
  261.                   {
  262.                     case 'C':
  263.                       solve_draw_or_clear='D';
  264.                       break;
  265.                     case 'S':
  266.                       solve_draw_or_clear='B';
  267.                       break;
  268.                     default:
  269.                       break;
  270.                   }
  271.                 WinInvalidateRect(hwnd,(PRECTL) NULL,(BOOL) FALSE);
  272.                 break;
  273.               default:
  274.                 break;
  275.             }
  276.           horizontal_scroll_position=max(0,min(horizontal_scroll_position,360));
  277.           if (horizontal_scroll_position
  278.            != SHORT1FROMMR(WinSendMsg(hwndHscroll,SBM_QUERYPOS,NULL,NULL)))
  279.             WinSendMsg(hwndHscroll,SBM_SETPOS,
  280.              MPFROMSHORT(horizontal_scroll_position),NULL);
  281.           break;
  282.         case WM_VSCROLL:
  283.           switch (SHORT2FROMMP(mp2))
  284.             {
  285.               case SB_LINEUP:
  286.                 vertical_scroll_position--;
  287.                 break;
  288.               case SB_LINEDOWN:
  289.                 vertical_scroll_position++;
  290.                 break;
  291.               case SB_PAGEUP:
  292.                 vertical_scroll_position-=10;
  293.                 break;
  294.               case SB_PAGEDOWN:
  295.                 vertical_scroll_position+=10;
  296.                 break;
  297.               case SB_SLIDERPOSITION:
  298.                 vertical_scroll_position=SHORT1FROMMP(mp2);
  299.               case SB_ENDSCROLL:
  300.                 plot_command=TRUE;
  301.                 DosQueryEventSem((HEV) plot_active,&plotting);
  302.                 if (plotting == (ULONG) 0)
  303.                   plot_kill=TRUE;
  304.                 DosQueryEventSem((HEV) SizeMaze_active,&sizing);
  305.                 if (sizing == (ULONG) 0)
  306.                   {
  307.                     SizeMaze_kill=TRUE;
  308.                     DosWaitEventSem((HEV) SizeMaze_active,
  309.                      (ULONG) SEM_INDEFINITE_WAIT);
  310.                   }
  311.                 if (plot_kill)
  312.                   {
  313.                     DosWaitEventSem((HEV) plot_active,
  314.                      (ULONG) SEM_INDEFINITE_WAIT);
  315.                     WinEndPaint(hPS);
  316.                   }
  317.                 tilt=(double) (((short) 90)-vertical_scroll_position);
  318.                 if ((iMaxX >= TWICE_PIXELS_PER_ROOM)
  319.                 &&  (iMaxY >= TWICE_PIXELS_PER_ROOM))
  320.                   {
  321.                     DosResetEventSem((HEV) SizeMaze_active,
  322.                      &SizeMaze_post_count);
  323.                     SizeMaze_kill=FALSE;
  324.                     DosCreateThread(&SizeMaze_thread_id,SizeMaze,(ULONG) 0,
  325.                      (ULONG) 0,16384);
  326.                   }
  327.                 switch (solve_draw_or_clear)
  328.                   {
  329.                     case 'C':
  330.                       solve_draw_or_clear='D';
  331.                       break;
  332.                     case 'S':
  333.                       solve_draw_or_clear='B';
  334.                       break;
  335.                     default:
  336.                       break;
  337.                   }
  338.                 WinInvalidateRect(hwnd,(PRECTL) NULL,(BOOL) FALSE);
  339.                 break;
  340.               default:
  341.                 break;
  342.             }
  343.           vertical_scroll_position=max(0,min(vertical_scroll_position,90));
  344.           if (vertical_scroll_position
  345.            != SHORT1FROMMR(WinSendMsg(hwndVscroll,SBM_QUERYPOS,NULL,NULL)))
  346.             WinSendMsg(hwndVscroll,SBM_SETPOS,
  347.              MPFROMSHORT(vertical_scroll_position),NULL);
  348.           break;
  349.         case WM_COMMAND:
  350.           hwndMenu=WinWindowFromID(WinQueryWindow((HWND) hwnd,(LONG) QW_PARENT),
  351.            (ULONG) FID_MENU);
  352.           switch (COMMANDMSG(&msg)->cmd)
  353.             {
  354.               case IDM_CLEAR:
  355.                 plot_command=TRUE;
  356.                 if (iFatalError)
  357.                   WinInvalidateRect(hwnd,(PRECTL) NULL,(BOOL) FALSE);
  358.                 else
  359.                   {
  360.                     DosQueryEventSem((HEV) SizeMaze_active,&sizing);
  361.                     DosQueryEventSem((HEV) plot_active,&plotting);
  362.                     if ((sizing == (ULONG) 0)
  363.                     ||  (plotting == (ULONG) 0))
  364.                       DosBeep((ULONG) 60,(ULONG) 333);
  365.                     else
  366.                       {
  367.                         solve_draw_or_clear=(int) 'C';
  368.                         WinInvalidateRect(hwnd,(PRECTL) NULL,(BOOL) FALSE);
  369.                       }
  370.                   }
  371.                 break;
  372.               case IDM_NEW:
  373.                 plot_command=TRUE;
  374.                 DosQueryEventSem((HEV) plot_active,&plotting);
  375.                 if (plotting == (ULONG) 0)
  376.                   plot_kill=TRUE;
  377.                 DosQueryEventSem((HEV) SizeMaze_active,&sizing);
  378.                 if (sizing == (ULONG) 0)
  379.                   {
  380.                     SizeMaze_kill=TRUE;
  381.                     DosWaitEventSem((HEV) SizeMaze_active,
  382.                      (ULONG) SEM_INDEFINITE_WAIT);
  383.                   }
  384.                 if (plot_kill)
  385.                   {
  386.                     DosWaitEventSem((HEV) plot_active,
  387.                      (ULONG) SEM_INDEFINITE_WAIT);
  388.                     WinEndPaint(hPS);
  389.                   }
  390.                 if ((iMaxX >= TWICE_PIXELS_PER_ROOM)
  391.                 &&  (iMaxY >= TWICE_PIXELS_PER_ROOM))
  392.                   {
  393.                     DosGetDateTime(&dateSeed);
  394.                     r_n_seed[0]=dateSeed.year%10;
  395.                     r_n_seed[1]=dateSeed.month%10;
  396.                     r_n_seed[2]=dateSeed.day%10;
  397.                     r_n_seed[3]=dateSeed.hours%10;
  398.                     r_n_seed[4]=dateSeed.minutes%10;
  399.                     r_n_seed[5]=dateSeed.seconds%10;
  400.                     r_n_seed[6]=dateSeed.hundredths%10;
  401.                     DosResetEventSem((HEV) SizeMaze_active,
  402.                      &SizeMaze_post_count);
  403.                     SizeMaze_kill=FALSE;
  404.                     DosCreateThread(&SizeMaze_thread_id,SizeMaze,(ULONG) 0,
  405.                      (ULONG) 0,16384);
  406.                   }
  407.                 solve_draw_or_clear=(int) 'D';
  408.                 WinInvalidateRect(hwnd,(PRECTL) NULL,(BOOL) FALSE);
  409.                 break;
  410.               case IDM_SOLVE:
  411.                 plot_command=TRUE;
  412.                 if (iFatalError)
  413.                   WinInvalidateRect(hwnd,(PRECTL) NULL,(BOOL) FALSE);
  414.                 else
  415.                   {
  416.                     DosQueryEventSem((HEV) SizeMaze_active,&sizing);
  417.                     DosQueryEventSem((HEV) plot_active,&plotting);
  418.                     if ((sizing == (ULONG) 0)
  419.                     ||  (plotting == (ULONG) 0))
  420.                       DosBeep(60,333);
  421.                     else
  422.                       {
  423.                         if ((iMaxX >= TWICE_PIXELS_PER_ROOM)
  424.                         &&  (iMaxY >= TWICE_PIXELS_PER_ROOM))
  425.                           solve_draw_or_clear=(int) 'S';
  426.                         WinInvalidateRect(hwnd,(PRECTL) NULL,(BOOL) FALSE);
  427.                       }
  428.                   }
  429.                 break;
  430.               case IDM_HELP:
  431.                 WinDlgBox(HWND_DESKTOP,hwnd,(PFNWP) HelpProc,(HMODULE) 0,
  432.                  (ULONG) IDD_HELPBOX,(PVOID) NULL);
  433.                 break;
  434.               default:
  435.                 break;
  436.             }
  437.           break;
  438.         case WM_SIZE:
  439.           DosQueryEventSem((HEV) plot_active,&plotting);
  440.           if (plotting == (ULONG) 0)
  441.             plot_kill=TRUE;
  442.           DosQueryEventSem((HEV) SizeMaze_active,&sizing);
  443.           if (sizing == (ULONG) 0)
  444.             {
  445.               SizeMaze_kill=TRUE;
  446.               DosWaitEventSem((HEV) SizeMaze_active,
  447.                (ULONG) SEM_INDEFINITE_WAIT);
  448.             }
  449.           if (plot_kill)
  450.             {
  451.               DosWaitEventSem((HEV) plot_active,(ULONG) SEM_INDEFINITE_WAIT);
  452.               WinEndPaint(hPS);
  453.             }
  454.           resized=TRUE;
  455.           solve_draw_or_clear=(int) 'D';
  456.           iMaxX=SHORT1FROMMP(mp2)-1;
  457.           iMaxY=SHORT2FROMMP(mp2)-1;
  458.           if ((iMaxX >= TWICE_PIXELS_PER_ROOM)
  459.           &&  (iMaxY >= TWICE_PIXELS_PER_ROOM))
  460.             {
  461.               DosGetDateTime(&dateSeed);
  462.               r_n_seed[0]=dateSeed.year%10;
  463.               r_n_seed[1]=dateSeed.month%10;
  464.               r_n_seed[2]=dateSeed.day%10;
  465.               r_n_seed[3]=dateSeed.hours%10;
  466.               r_n_seed[4]=dateSeed.minutes%10;
  467.               r_n_seed[5]=dateSeed.seconds%10;
  468.               r_n_seed[6]=dateSeed.hundredths%10;
  469.               DosResetEventSem((HEV) SizeMaze_active,&SizeMaze_post_count);
  470.               SizeMaze_kill=FALSE;
  471.               DosCreateThread(&SizeMaze_thread_id,SizeMaze,(ULONG) 0,(ULONG) 0,
  472.                16384);
  473.             }
  474.           break;
  475.         case WM_ERASEBACKGROUND:
  476.           return((MRESULT) TRUE); 
  477.           break;
  478.         case WM_PAINT:
  479.           DosQueryEventSem((HEV) plot_active,&plotting);
  480.           if (plotting == (ULONG) 0)
  481.             {
  482.               plot_kill=TRUE;
  483.               DosWaitEventSem((HEV) plot_active,(ULONG) SEM_INDEFINITE_WAIT);
  484.               WinEndPaint(hPS);
  485.               WinInvalidateRect(hwnd,(PRECTL) NULL,(BOOL) FALSE);
  486.             }
  487.           plot_hwnd=hwnd;
  488.           if ((iMaxX >= TWICE_PIXELS_PER_ROOM)
  489.           &&  (iMaxY >= TWICE_PIXELS_PER_ROOM))
  490.             {
  491.               DosResetEventSem((HEV) plot_active,&plot_post_count);
  492.               hPS=WinBeginPaint(hwnd,(HPS) NULL,(PRECTL) NULL);
  493.               plot_kill=FALSE;
  494.               if ((! resized) && (! plot_command))
  495.                 switch (solve_draw_or_clear)
  496.                   {
  497.                     case 'C':
  498.                       solve_draw_or_clear='D';
  499.                       break;
  500.                     case 'S':
  501.                       solve_draw_or_clear='B';
  502.                       break;
  503.                     default:
  504.                       break;
  505.                   }
  506.               DosCreateThread(&plot_thread_id,plot,(ULONG) 0,(ULONG) 0,16384);
  507.             }
  508.           resized=FALSE;
  509.           plot_command=FALSE;
  510.           break;
  511.         case WM_PLOT_DONE:
  512.           WinEndPaint(hPS);
  513.           break;
  514.         case WM_DESTROY:
  515.           DosQueryEventSem((HEV) plot_active,&plotting);
  516.           if (plotting == (ULONG) 0)
  517.             plot_kill=TRUE;
  518.           DosQueryEventSem((HEV) SizeMaze_active,&sizing);
  519.           if (sizing == (ULONG) 0)
  520.             {
  521.               SizeMaze_kill=TRUE;
  522.               DosWaitEventSem((HEV) SizeMaze_active,
  523.                (ULONG) SEM_INDEFINITE_WAIT);
  524.             }
  525.           if (plot_kill)
  526.             {
  527.               DosWaitEventSem((HEV) plot_active,(ULONG) SEM_INDEFINITE_WAIT);
  528.               WinEndPaint(hPS);
  529.             }
  530.           DestroyMaze(&x_prime,&y_prime,&z_prime,&x_division_index,
  531.            &y_division_index,&color,&base_z,&stack);
  532.           break;
  533.         default:
  534.           return(WinDefWindowProc(hwnd,msg,mp1,mp2));
  535.           break;
  536.       }
  537.     return((MRESULT) 0);
  538.   }
  539.  
  540. MRESULT EXPENTRY HelpProc(HWND hwnd,ULONG msg,MPARAM mp1,MPARAM mp2)
  541.   {
  542.     switch (msg)
  543.       {
  544.         case WM_COMMAND:
  545.           switch (COMMANDMSG(&msg)->cmd)
  546.             {
  547.               case DID_OK:
  548.               case DID_CANCEL:
  549.                 WinDismissDlg(hwnd,(ULONG) TRUE);
  550.                 break;
  551.               default:
  552.                 break;
  553.             }
  554.           break;
  555.         default:
  556.           return(WinDefDlgProc(hwnd,msg,mp1,mp2));
  557.       }
  558.     return((MRESULT) 0);
  559.   }
  560.  
  561. static void SizeMaze(arg)
  562.   ULONG arg;
  563.     {
  564.       num_columns=iMaxX/PIXELS_PER_ROOM;
  565.       num_rows=iMaxY/PIXELS_PER_ROOM;
  566.       max_x=2*num_columns;
  567.       max_y=2*num_rows;
  568.       num_rooms_in_maze=num_rows*num_columns;
  569.       num_x_divisions=RESOLUTION*(max_y+1)+2-RESOLUTION/2;
  570.       if (RESOLUTION%2 == 0)
  571.         num_x_divisions++;
  572.       num_y_divisions=RESOLUTION*(max_x+1)+2-RESOLUTION/2;
  573.       if (RESOLUTION%2 == 0)
  574.         num_y_divisions++;
  575.       num_primes=(long) num_x_divisions;
  576.       num_primes*=((long) num_y_divisions);
  577.       DestroyMaze(&x_prime,&y_prime,&z_prime,&x_division_index,
  578.        &y_division_index,&color,&base_z,&stack);
  579.       max_x_plus_1=max_x+1;
  580.       max_x_less_1=max_x-1;
  581.       max_y_plus_1=max_y+1;
  582.       max_y_less_1=max_y-1;
  583.       if (! SizeMaze_kill)
  584.         {
  585.           if (memory_allocated(num_primes,&x_prime,&y_prime,
  586.            &z_prime,&x_division_index,&y_division_index,&color,&base_z,
  587.            num_rooms_in_maze,&stack))
  588.             {
  589.               if (! SizeMaze_kill)
  590.                 generate_maze();
  591.               x_min=1.0;
  592.               x_max=(double) num_x_divisions;
  593.               y_min=1.0;
  594.               y_max=(double) num_y_divisions;
  595.               light.x=1.5;
  596.               light.y=-1.0;
  597.               light.z=2.6;
  598.               if (! SizeMaze_kill)
  599.                 evaluate_and_transform(x_min,x_max,y_min,y_max,num_x_divisions,
  600.                  num_y_divisions,rotation,tilt,x_prime,y_prime,z_prime,
  601.                  &x_prime_max,&y_prime_min,&y_prime_max,&z_prime_min,
  602.                  &z_prime_max,&light,x_division_index,y_division_index,base_z);
  603.               if (! SizeMaze_kill)
  604.                 shade(num_x_divisions,num_y_divisions,x_prime,y_prime,z_prime,
  605.                  color,&light);
  606.               if (! SizeMaze_kill)
  607.                 adjust_perspective(num_x_divisions,num_y_divisions,x_prime,
  608.                  y_prime,z_prime,x_prime_max,y_prime_min,y_prime_max,
  609.                  z_prime_min,z_prime_max);
  610.               if (! SizeMaze_kill)
  611.                 sort_back_to_front(num_primes,x_prime,x_division_index,
  612.                  y_division_index);
  613.             }
  614.           else
  615.             iFatalError=TRUE;
  616.         }
  617.       DosEnterCritSec();
  618.       DosPostEventSem((HEV) SizeMaze_active);
  619.       return;
  620.     }
  621.  
  622. static int memory_allocated(num_primes,x_prime,y_prime,z_prime,x_division_index,
  623.  y_division_index,color,base_z,num_rooms_in_maze,stack)
  624.   long               num_primes;
  625.   float              **x_prime;
  626.   float              **y_prime;
  627.   float              **z_prime;
  628.   int                **x_division_index;
  629.   int                **y_division_index;
  630.   unsigned char      **color;
  631.   unsigned char      **base_z;
  632.   int                num_rooms_in_maze;
  633.   stack_rec          **stack;
  634.     {
  635.       static   int result;
  636.       register int y;
  637.  
  638.       if (result=((page=(char **) malloc(max_y_plus_1*sizeof(char *))) != NULL))
  639.         {
  640.           for (y=0; ((result) && (y < max_y_plus_1)); y++)
  641.             result=((page[y]=malloc(max_x_plus_1*sizeof(char))) != NULL);
  642.           if (! result)
  643.             {
  644.               while (y > 0)
  645.                 free((void *) page[--y]);
  646.               free((void *) page);
  647.               page=(char **) NULL;
  648.             }
  649.         }
  650.       if (result)
  651.         {
  652.           if (! (result=((*x_prime=(float *) malloc(num_primes*sizeof(float)))
  653.            != NULL)))
  654.             {
  655.               for (y=0; y < max_y_plus_1; y++)
  656.                 free((void *) page[y]);
  657.               free((void *) page);
  658.               page=(char **) NULL;
  659.             }
  660.         }
  661.       if (result)
  662.         {
  663.           if (! (result=((*y_prime
  664.            =(float *) malloc(num_primes*sizeof(float))) != NULL)))
  665.             {
  666.               free((void *) *x_prime);
  667.               *x_prime=(float *) NULL;
  668.               for (y=0; y < max_y_plus_1; y++)
  669.                 free((void *) page[y]);
  670.               free((void *) page);
  671.               page=(char **) NULL;
  672.             }
  673.         }
  674.       if (result)
  675.         {
  676.           if (! (result=((*z_prime
  677.            =(float *) malloc(num_primes*sizeof(float))) != NULL)))
  678.             {
  679.               free((void *) *y_prime);
  680.               *y_prime=(float *) NULL;
  681.               free((void *) *x_prime);
  682.               *x_prime=(float *) NULL;
  683.               for (y=0; y < max_y_plus_1; y++)
  684.                 free((void *) page[y]);
  685.               free((void *) page);
  686.               page=(char **) NULL;
  687.             }
  688.         }
  689.       if (result)
  690.         {
  691.           if (! (result=((*x_division_index
  692.            =(int *) malloc(num_primes*sizeof(int))) != NULL)))
  693.             {
  694.               free((void *) *z_prime);
  695.               *z_prime=(float *) NULL;
  696.               free((void *) *y_prime);
  697.               *y_prime=(float *) NULL;
  698.               free((void *) *x_prime);
  699.               *x_prime=(float *) NULL;
  700.               for (y=0; y < max_y_plus_1; y++)
  701.                 free((void *) page[y]);
  702.               free((void *) page);
  703.               page=(char **) NULL;
  704.             }
  705.         }
  706.       if (result)
  707.         {
  708.           if (! (result=((*y_division_index
  709.            =(int *) malloc(num_primes*sizeof(int))) != NULL)))
  710.             {
  711.               free((void *) *x_division_index);
  712.               *x_division_index=(int *) NULL;
  713.               free((void *) *z_prime);
  714.               *z_prime=(float *) NULL;
  715.               free((void *) *y_prime);
  716.               *y_prime=(float *) NULL;
  717.               free((void *) *x_prime);
  718.               *x_prime=(float *) NULL;
  719.               for (y=0; y < max_y_plus_1; y++)
  720.                 free((void *) page[y]);
  721.               free((void *) page);
  722.               page=(char **) NULL;
  723.             }
  724.         }
  725.       if (result)
  726.         {
  727.           if (! (result=((*color=(unsigned char *) 
  728.            malloc(num_primes*sizeof(unsigned char))) != NULL)))
  729.             {
  730.               free((void *) *y_division_index);
  731.               *y_division_index=(int *) NULL;
  732.               free((void *) *x_division_index);
  733.               *x_division_index=(int *) NULL;
  734.               free((void *) *z_prime);
  735.               *z_prime=(float *) NULL;
  736.               free((void *) *y_prime);
  737.               *y_prime=(float *) NULL;
  738.               free((void *) *x_prime);
  739.               *x_prime=(float *) NULL;
  740.               for (y=0; y < max_y_plus_1; y++)
  741.                 free((void *) page[y]);
  742.               free((void *) page);
  743.               page=(char **) NULL;
  744.             }
  745.         }
  746.       if (result)
  747.         {
  748.           if (! (result=((*base_z=(unsigned char *) 
  749.            malloc(num_primes*sizeof(unsigned char))) != NULL)))
  750.             {
  751.               free((void *) *color);
  752.               *color=(unsigned char *) NULL;
  753.               free((void *) *y_division_index);
  754.               *y_division_index=(int *) NULL;
  755.               free((void *) *x_division_index);
  756.               *x_division_index=(int *) NULL;
  757.               free((void *) *z_prime);
  758.               *z_prime=(float *) NULL;
  759.               free((void *) *y_prime);
  760.               *y_prime=(float *) NULL;
  761.               free((void *) *x_prime);
  762.               *x_prime=(float *) NULL;
  763.               for (y=0; y < max_y_plus_1; y++)
  764.                 free((void *) page[y]);
  765.               free((void *) page);
  766.               page=(char **) NULL;
  767.             }
  768.         }
  769.       if (result)
  770.         {
  771.           if (! (result=((*stack
  772.            =(stack_rec *) malloc(num_rooms_in_maze*sizeof(stack_rec)))
  773.            != NULL)))
  774.             {
  775.               free((void *) *base_z);
  776.               *base_z=(unsigned char *) NULL;
  777.               free((void *) *color);
  778.               *color=(unsigned char *) NULL;
  779.               free((void *) *y_division_index);
  780.               *y_division_index=(int *) NULL;
  781.               free((void *) *x_division_index);
  782.               *x_division_index=(int *) NULL;
  783.               free((void *) *z_prime);
  784.               *z_prime=(float *) NULL;
  785.               free((void *) *y_prime);
  786.               *y_prime=(float *) NULL;
  787.               free((void *) *x_prime);
  788.               *x_prime=(float *) NULL;
  789.               for (y=0; y < max_y_plus_1; y++)
  790.                 free((void *) page[y]);
  791.               free((void *) page);
  792.               page=(char **) NULL;
  793.             }
  794.         }
  795.       return(result);
  796.     }
  797.  
  798. static int num_rooms_in_solution()
  799.     {
  800.       int direction_x;
  801.       int direction_y;
  802.       int initial_direction_x;
  803.       int initial_direction_y;
  804.       int passage_found;
  805.       int result;
  806.       int tem;
  807.       int x;
  808.       int x_next;
  809.       int y;
  810.       int y_next;
  811.  
  812.       result=1;
  813.       x=1;
  814.       y=1;
  815.       page[y][x]='S';
  816.       initial_direction_x=0;
  817.       initial_direction_y=1;
  818.       do
  819.         {
  820.           passage_found=FALSE;
  821.           direction_x=-initial_direction_y;
  822.           direction_y=initial_direction_x;
  823.           while (! passage_found)
  824.             {
  825.               x_next=x+direction_x;
  826.               y_next=y+direction_y;
  827.               if (page[y_next][x_next] != 'W')
  828.                 passage_found=TRUE;
  829.               else
  830.                 {
  831.                   tem=direction_x;
  832.                   direction_x=direction_y;
  833.                   direction_y=-tem;
  834.                 }
  835.             };
  836.           if (page[y_next][x_next] == ' ')
  837.             {
  838.               result++;
  839.               page[y_next][x_next]='S';
  840.               x=x_next+direction_x;
  841.               y=y_next+direction_y;
  842.               page[y][x]='S';
  843.             }
  844.           else
  845.             {
  846.               result--;
  847.               page[y][x]=' ';
  848.               page[y_next][x_next]=' ';
  849.               x=x_next+direction_x;
  850.               y=y_next+direction_y;
  851.             };
  852.           initial_direction_x=direction_x;
  853.           initial_direction_y=direction_y;
  854.         }
  855.       while ((x != max_x_less_1) || (y != max_y_less_1));
  856.       return(result);
  857.     }
  858.  
  859. static void generate_maze()
  860.     {
  861.       static   int       counter_0;
  862.       static   int       counter_1;
  863.       static   int       counter_2;
  864.       static   int       counter_3;
  865.       static   int       counter_4;
  866.       static   int       counter_5;
  867.       static   int       counter_6;
  868.       static   int       counter_7;
  869.       static   int       delta_index_1a;
  870.       static   int       delta_index_1b;
  871.       static   int       delta_index_1c;
  872.       static   int       delta_index_1d;
  873.       static   int       delta_index_2;
  874.       static   int       digit;
  875.       static   int       digit_num;
  876.       static   int       passage_found;
  877.       register int       r_n_index_1;
  878.       register int       r_n_index_2;
  879.       static   int       search_complete;
  880.       static   int       stack_head;
  881.       static   int       sum;
  882.       static   int       tem_int;
  883.       static   int       x;
  884.       static   int       x_next;
  885.       static   int       y;
  886.       static   int       y_next;
  887.  
  888.       r_n[0]=r_n_seed[0];
  889.       r_n[1]=r_n_seed[1];
  890.       r_n[2]=r_n_seed[2];
  891.       r_n[3]=r_n_seed[3];
  892.       r_n[4]=r_n_seed[4];
  893.       r_n[5]=r_n_seed[5];
  894.       r_n[6]=r_n_seed[6];
  895.       r_n[7]=0;
  896.       counter_0=r_n[0];
  897.       counter_1=r_n[1];
  898.       counter_2=r_n[2];
  899.       counter_3=r_n[3];
  900.       counter_4=r_n[4];
  901.       counter_5=r_n[5];
  902.       counter_6=r_n[6];
  903.       counter_7=r_n[7];
  904.       hash(&counter_0,&counter_1,&counter_2,&counter_3,&counter_4,&counter_5,
  905.        &counter_6,&counter_7);
  906.       delta_x[0][0]=-1;
  907.       delta_y[0][0]=0;
  908.       delta_x[1][0]=0;
  909.       delta_y[1][0]=1;
  910.       delta_x[2][0]=1;
  911.       delta_y[2][0]=0;
  912.       delta_x[3][0]=0;
  913.       delta_y[3][0]=-1;
  914.       delta_index_2=0;
  915.       for (delta_index_1a=0; delta_index_1a < 4; ++delta_index_1a)
  916.         for (delta_index_1b=0; delta_index_1b < 4; ++delta_index_1b)
  917.           if (delta_index_1a != delta_index_1b)
  918.             for (delta_index_1c=0; delta_index_1c < 4; ++delta_index_1c)
  919.               if ((delta_index_1a != delta_index_1c)
  920.               &&  (delta_index_1b != delta_index_1c))
  921.                 for (delta_index_1d=0; delta_index_1d < 4; ++delta_index_1d)
  922.                   if ((delta_index_1a != delta_index_1d)
  923.                   &&  (delta_index_1b != delta_index_1d)
  924.                   &&  (delta_index_1c != delta_index_1d))
  925.                     {
  926.                       delta_x[delta_index_1a][delta_index_2]=delta_x[0][0];
  927.                       delta_y[delta_index_1a][delta_index_2]=delta_y[0][0];
  928.                       delta_x[delta_index_1b][delta_index_2]=delta_x[1][0];
  929.                       delta_y[delta_index_1b][delta_index_2]=delta_y[1][0];
  930.                       delta_x[delta_index_1c][delta_index_2]=delta_x[2][0];
  931.                       delta_y[delta_index_1c][delta_index_2]=delta_y[2][0];
  932.                       delta_x[delta_index_1d][delta_index_2]=delta_x[3][0];
  933.                       delta_y[delta_index_1d][delta_index_2]=delta_y[3][0];
  934.                       delta_index_2++;
  935.                     };
  936.       do
  937.         {
  938.           for (y=0; y <= max_y; ++y)
  939.             for (x=0; x <= max_x; ++x)
  940.               page[y][x]='W';
  941.           r_n[0]=counter_0+1;
  942.           r_n[1]=counter_1+1;
  943.           r_n[2]=counter_2+1;
  944.           r_n[3]=counter_3+1;
  945.           r_n[4]=counter_4+1;
  946.           r_n[5]=counter_5+1;
  947.           r_n[6]=counter_6+1;
  948.           r_n[7]=counter_7+1;
  949.           sum=0;
  950.           for (digit_num=1; digit_num <= 3; ++digit_num)
  951.             {
  952.               digit=r_n[0];
  953.               r_n_index_1=0;
  954.               for (r_n_index_2=1; r_n_index_2 < 8; ++r_n_index_2)
  955.                 {
  956.                   tem_int=r_n[r_n_index_2];
  957.                   r_n[r_n_index_1]=tem_int;
  958.                   digit+=tem_int;
  959.                   if (digit >= 29)
  960.                      digit-=29;
  961.                   r_n_index_1=r_n_index_2;
  962.                 }
  963.               r_n[7]=digit;
  964.               sum=29*sum+digit;
  965.             }
  966.           x=2*(sum % num_columns)+1;
  967.           sum=0;
  968.           for (digit_num=1; digit_num <= 3; ++digit_num)
  969.             {
  970.               digit=r_n[0];
  971.               r_n_index_1=0;
  972.               for (r_n_index_2=1; r_n_index_2 < 8; ++r_n_index_2)
  973.                 {
  974.                   tem_int=r_n[r_n_index_2];
  975.                   r_n[r_n_index_1]=tem_int;
  976.                   digit+=tem_int;
  977.                   if (digit >= 29)
  978.                      digit-=29;
  979.                   r_n_index_1=r_n_index_2;
  980.                 }
  981.               r_n[7]=digit;
  982.               sum=29*sum+digit;
  983.             }
  984.           y=2*(sum % num_rows)+1;
  985.           page[y][x]=' ';
  986.           stack_head=-1;
  987.           do
  988.             {
  989.               delta_index_1a=0;
  990.               do
  991.                 {
  992.                   delta_index_2=r_n[0];
  993.                   r_n_index_1=0;
  994.                   r_n_index_2=1;
  995.                   while (r_n_index_2 < 8)
  996.                     {
  997.                       tem_int=r_n[r_n_index_2];
  998.                       r_n[r_n_index_1]=tem_int;
  999.                       delta_index_2+=tem_int;
  1000.                       if (delta_index_2 >= 29)
  1001.                         delta_index_2-=29;
  1002.                       r_n_index_1=r_n_index_2;
  1003.                       r_n_index_2++;
  1004.                     }
  1005.                   r_n[7]=delta_index_2;
  1006.                 }
  1007.               while (delta_index_2 >= 24);
  1008.               passage_found=FALSE;
  1009.               search_complete=FALSE;
  1010.               while (! search_complete)
  1011.                 {
  1012.                   while ((delta_index_1a < 4) && (! passage_found))
  1013.                     {
  1014.                       x_next=x+2*delta_x[delta_index_1a][delta_index_2];
  1015.                       if (x_next <= 0)
  1016.                         delta_index_1a++;
  1017.                       else
  1018.                         if (x_next >= max_x)
  1019.                           delta_index_1a++;
  1020.                         else
  1021.                           {
  1022.                             y_next=y+2*delta_y[delta_index_1a][delta_index_2];
  1023.                             if (y_next <= 0)
  1024.                               delta_index_1a++;
  1025.                             else
  1026.                               if (y_next >= max_y)
  1027.                                 delta_index_1a++;
  1028.                               else
  1029.                                 if (page[y_next][x_next] == 'W')
  1030.                                   passage_found=TRUE;
  1031.                                 else
  1032.                                   delta_index_1a++;
  1033.                           }
  1034.                     }
  1035.                   if (! passage_found)
  1036.                     {
  1037.                       delta_index_1a=(int) (stack[stack_head].index_1);
  1038.                       delta_index_2=(int) (stack[stack_head].index_2);
  1039.                       x-=2*delta_x[delta_index_1a][delta_index_2];
  1040.                       y-=2*delta_y[delta_index_1a][delta_index_2];
  1041.                       stack_head--;
  1042.                       delta_index_1a++;
  1043.                     }
  1044.                   search_complete=((passage_found) || (stack_head == -1));
  1045.                 }
  1046.               if (passage_found)
  1047.                 {
  1048.                   stack_head++;
  1049.                   stack[stack_head].index_1=(char) delta_index_1a;
  1050.                   stack[stack_head].index_2=(char) delta_index_2;
  1051.                   page[y_next][x_next]=' ';
  1052.                   if (x == x_next)
  1053.                     page[(y+y_next)/2][x_next]=' ';
  1054.                   else
  1055.                     page[y_next][(x+x_next)/2]=' ';
  1056.                   x=x_next;
  1057.                   y=y_next;
  1058.                 }
  1059.             }
  1060.           while (stack_head != -1);
  1061.           page[0][1]=' ';
  1062.           page[max_y][max_x-1]=' ';
  1063.           increment(&counter_0,&counter_1,&counter_2,&counter_3,&counter_4,
  1064.            &counter_5,&counter_6,&counter_7);
  1065.         }
  1066.       while ((! SizeMaze_kill)
  1067.       &&     (3*num_rooms_in_solution() < num_rooms_in_maze));
  1068.       return;
  1069.     }
  1070.  
  1071. static int substitution_high [100] =
  1072.              { 4,1,2,8,8,9,9,6,5,7,2,1,2,9,8,8,6,3,5,1,9,5,4,4,9,8,6,0,8,0,
  1073.                6,0,2,4,1,9,2,0,7,4,7,3,0,0,2,6,8,9,4,0,8,3,2,3,2,5,2,4,6,9,
  1074.                7,9,1,3,5,7,1,1,4,5,8,1,6,0,5,7,8,2,3,3,7,3,5,1,7,5,4,0,3,6,
  1075.                3,7,7,1,9,4,0,5,6,6 
  1076.              };
  1077. static int substitution_low [100] =
  1078.              { 1,2,2,1,5,5,4,6,4,6,4,4,5,6,6,3,0,9,6,5,7,2,0,9,3,4,2,3,9,1,
  1079.                9,9,9,3,8,9,3,4,1,5,0,5,2,7,0,8,8,0,4,5,0,3,6,8,1,7,8,8,7,1,
  1080.                3,2,7,7,1,8,0,3,7,5,2,6,4,0,9,9,7,7,4,6,2,0,0,1,7,3,6,6,1,1,
  1081.                2,4,5,9,8,2,8,8,3,5 
  1082.              };
  1083. static void hash(counter_0,counter_1,counter_2,counter_3,counter_4,counter_5,
  1084.  counter_6,counter_7)
  1085.   int *counter_0;
  1086.   int *counter_1;
  1087.   int *counter_2;
  1088.   int *counter_3;
  1089.   int *counter_4;
  1090.   int *counter_5;
  1091.   int *counter_6;
  1092.   int *counter_7;
  1093.     {
  1094.       register int iteration;
  1095.       static   int seed_0;
  1096.       static   int seed_1;
  1097.       static   int seed_2;
  1098.       static   int seed_3;
  1099.       static   int seed_4;
  1100.       static   int seed_5;
  1101.       static   int seed_6;
  1102.       static   int seed_7;
  1103.       register int substitution_index;
  1104.       static   int tem_0;
  1105.       static   int tem_1;
  1106.       static   int tem_2;
  1107.  
  1108.       seed_0=(*counter_0);
  1109.       seed_1=(*counter_1);
  1110.       seed_2=(*counter_2);
  1111.       seed_3=(*counter_3);
  1112.       seed_4=(*counter_4);
  1113.       seed_5=(*counter_5);
  1114.       seed_6=(*counter_6);
  1115.       seed_7=(*counter_7);
  1116.       for (iteration=1; iteration <= 8; iteration++)
  1117.         {
  1118.           substitution_index=10*seed_1+seed_0;
  1119.           tem_0=substitution_low[substitution_index];
  1120.           tem_1=substitution_high[substitution_index];
  1121.           substitution_index=10*seed_3+seed_2;
  1122.           seed_0=substitution_low[substitution_index];
  1123.           tem_2=substitution_high[substitution_index];
  1124.           substitution_index=10*seed_5+seed_4;
  1125.           seed_2=substitution_low[substitution_index];
  1126.           seed_1=substitution_high[substitution_index];
  1127.           substitution_index=10*seed_7+seed_6;
  1128.           seed_5=substitution_low[substitution_index];
  1129.           seed_7=substitution_high[substitution_index];
  1130.           seed_3=tem_0;
  1131.           seed_6=tem_1;
  1132.           seed_4=tem_2;
  1133.         }
  1134.       (*counter_0)=seed_0;
  1135.       (*counter_1)=seed_1;
  1136.       (*counter_2)=seed_2;
  1137.       (*counter_3)=seed_3;
  1138.       (*counter_4)=seed_4;
  1139.       (*counter_5)=seed_5;
  1140.       (*counter_6)=seed_6;
  1141.       (*counter_7)=seed_7;
  1142.       return;
  1143.     }
  1144.  
  1145. static void increment(counter_0,counter_1,counter_2,counter_3,counter_4,
  1146.  counter_5,counter_6,counter_7)
  1147.   int *counter_0;
  1148.   int *counter_1;
  1149.   int *counter_2;
  1150.   int *counter_3;
  1151.   int *counter_4;
  1152.   int *counter_5;
  1153.   int *counter_6;
  1154.   int *counter_7;
  1155.     {
  1156.       register tem;
  1157.  
  1158.       tem=(*counter_0)+1;
  1159.       if (tem <= 9)
  1160.         (*counter_0)=tem;
  1161.       else
  1162.         {
  1163.           (*counter_0)=0;
  1164.           tem=(*counter_1)+1;
  1165.           if (tem <= 9)
  1166.             (*counter_1)=tem;
  1167.           else
  1168.             {
  1169.               (*counter_1)=0;
  1170.               tem=(*counter_2)+1;
  1171.               if (tem <= 9)
  1172.                 (*counter_2)=tem;
  1173.               else
  1174.                 {
  1175.                   (*counter_2)=0;
  1176.                   tem=(*counter_3)+1;
  1177.                   if (tem <= 9)
  1178.                     (*counter_3)=tem;
  1179.                   else
  1180.                     {
  1181.                       (*counter_3)=0;
  1182.                       tem=(*counter_4)+1;
  1183.                       if (tem <= 9)
  1184.                         (*counter_4)=tem;
  1185.                       else
  1186.                         {
  1187.                           (*counter_4)=0;
  1188.                           tem=(*counter_5)+1;
  1189.                           if (tem <= 9)
  1190.                             (*counter_5)=tem;
  1191.                           else
  1192.                             {
  1193.                               (*counter_5)=0;
  1194.                               tem=(*counter_6)+1;
  1195.                               if (tem <= 9)
  1196.                                 (*counter_6)=tem;
  1197.                               else
  1198.                                 {
  1199.                                   (*counter_6)=0;
  1200.                                   tem=(*counter_7)+1;
  1201.                                   if (tem <= 9)
  1202.                                     (*counter_7)=tem;
  1203.                                   else
  1204.                                     (*counter_7)=0;
  1205.                                 }
  1206.                             }
  1207.                         }
  1208.                     }
  1209.                 }
  1210.             }
  1211.         }
  1212.       return;
  1213.     }
  1214.  
  1215. static void evaluate_and_transform(x_min,x_max,y_min,y_max,num_x_divisions,
  1216.  num_y_divisions,rotation,tilt,x_prime,y_prime,z_prime,x_prime_max,y_prime_min,
  1217.  y_prime_max,z_prime_min,z_prime_max,light,x_division_index,y_division_index,
  1218.  base_z)
  1219.   double             x_min;
  1220.   double             x_max;
  1221.   double             y_min;
  1222.   double             y_max;
  1223.   int                num_x_divisions;
  1224.   int                num_y_divisions;
  1225.   double             rotation;
  1226.   double             tilt;
  1227.   float              *x_prime;
  1228.   float              *y_prime;
  1229.   float              *z_prime;
  1230.   double             *x_prime_max;
  1231.   double             *y_prime_min;
  1232.   double             *y_prime_max;
  1233.   double             *z_prime_min;
  1234.   double             *z_prime_max;
  1235.   vertex_rec         *light;
  1236.   int                *x_division_index;
  1237.   int                *y_division_index;
  1238.   unsigned char      *base_z;
  1239.     {
  1240.       static   double cos_rotation;
  1241.       static   double cos_tilt;
  1242.       static   double magnitude;
  1243.       static   long   prime_num;
  1244.       static   double radians;
  1245.       static   double radians_per_degree;
  1246.       static   double sin_rotation;
  1247.       static   double sin_tilt;
  1248.       static   double x;
  1249.       static   double x_delta;
  1250.       register int    x_division_num;
  1251.       static   double x_rotated;
  1252.       static   double y;
  1253.       static   double y_delta;
  1254.       register int    y_division_num;
  1255.       static   double z;
  1256.  
  1257.       radians_per_degree=atan(1.0)/45.0;
  1258.       radians=tilt*radians_per_degree;
  1259.       cos_tilt=cos(radians);
  1260.       sin_tilt=sin(radians);
  1261.       radians=rotation*radians_per_degree;
  1262.       cos_rotation=cos(radians);
  1263.       sin_rotation=sin(radians);
  1264.       z=fabs(f(x_min,y_min));
  1265.       x_rotated=x_min*cos_rotation+y_min*sin_rotation;
  1266.       *y_prime_min=-x_min*sin_rotation+y_min*cos_rotation;
  1267.       *z_prime_min=-x_rotated*sin_tilt+z*cos_tilt;
  1268.       *y_prime_max=*y_prime_min;
  1269.       *z_prime_max=*z_prime_min;
  1270.       *x_prime_max=x_rotated*cos_tilt+z*sin_tilt;
  1271.       x_delta=(double) (num_x_divisions-1);
  1272.       x_delta=(x_max-x_min)/x_delta;
  1273.       y_delta=(double) (num_y_divisions-1);
  1274.       y_delta=(y_max-y_min)/y_delta;
  1275.       x=x_min;
  1276.       prime_num=0l;
  1277.       for (x_division_num=0; 
  1278.        ((! SizeMaze_kill) && (x_division_num < num_x_divisions));
  1279.        x_division_num++)
  1280.         {
  1281.           y=y_min;
  1282.           for (y_division_num=0; 
  1283.            ((! SizeMaze_kill) && (y_division_num < num_y_divisions));
  1284.            y_division_num++)
  1285.             {
  1286.               z=f(x,y);
  1287.               if (z > 0.0)
  1288.                 base_z[prime_num]=(unsigned char) 1;
  1289.               else
  1290.                 if (z < 0.0)
  1291.                   base_z[prime_num]=(unsigned char) 2;
  1292.                 else
  1293.                   base_z[prime_num]=(unsigned char) 0;
  1294.               z=fabs(z);
  1295.               x_division_index[prime_num]=x_division_num;
  1296.               y_division_index[prime_num]=y_division_num;
  1297.               x_rotated=x*cos_rotation+y*sin_rotation;
  1298.               y_prime[prime_num]=(float) (-x*sin_rotation+y*cos_rotation);
  1299.               x_prime[prime_num]=(float) (x_rotated*cos_tilt+z*sin_tilt);
  1300.               z_prime[prime_num]=(float) (-x_rotated*sin_tilt+z*cos_tilt);
  1301.               if (((double) (x_prime[prime_num])) > *x_prime_max)
  1302.                 *x_prime_max=(double) (x_prime[prime_num]);
  1303.               if (((double) (y_prime[prime_num])) < *y_prime_min)
  1304.                 *y_prime_min=(double) (y_prime[prime_num]);
  1305.               if (((double) (y_prime[prime_num])) > *y_prime_max)
  1306.                 *y_prime_max=(double) (y_prime[prime_num]);
  1307.               if (((double) (z_prime[prime_num])) < *z_prime_min)
  1308.                 *z_prime_min=(double) (z_prime[prime_num]);
  1309.               if (((double) (z_prime[prime_num])) > *z_prime_max)
  1310.                 *z_prime_max=(double) (z_prime[prime_num]);
  1311.               y+=y_delta;
  1312.               prime_num++;
  1313.             }
  1314.           x+=x_delta;
  1315.         }
  1316.       if ((! SizeMaze_kill))
  1317.         {
  1318.           magnitude=(*light).x*(*light).x;
  1319.           magnitude+=((*light).y*(*light).y);
  1320.           magnitude+=((*light).z*(*light).z);
  1321.           magnitude=sqrt(magnitude);
  1322.           (*light).x/=magnitude;
  1323.           (*light).y/=magnitude;
  1324.           (*light).z/=magnitude;
  1325.         }
  1326.       return;
  1327.     }
  1328.  
  1329. static void shade(num_x_divisions,num_y_divisions,x_prime,y_prime,z_prime,color,
  1330.  light)
  1331.   int                num_x_divisions;
  1332.   int                num_y_divisions;
  1333.   float              *x_prime;
  1334.   float              *y_prime;
  1335.   float              *z_prime;
  1336.   unsigned char      *color;
  1337.   vertex_rec         *light;
  1338.     {
  1339.       static   double     magnitude;
  1340.       static   vertex_rec normal;
  1341.       static   long       prime_num;
  1342.       static   vertex_rec vertex [4];
  1343.       register int        x_division_num;
  1344.       register int        y_division_num;
  1345.  
  1346.       prime_num=0l;
  1347.       for (x_division_num=0;
  1348.        ((! SizeMaze_kill) && (x_division_num < num_x_divisions));
  1349.        x_division_num++)
  1350.         {
  1351.           for (y_division_num=0; 
  1352.            ((! SizeMaze_kill) && (y_division_num < num_y_divisions));
  1353.            y_division_num++)
  1354.             {
  1355.               vertex[0].x=(double) (x_prime[prime_num]);
  1356.               vertex[0].y=(double) (y_prime[prime_num]);
  1357.               vertex[0].z=(double) (z_prime[prime_num]);
  1358.               if (x_division_num < (num_x_divisions-1))
  1359.                 if (y_division_num < (num_y_divisions-1))
  1360.                   {
  1361.                     prime_num+=((long) num_y_divisions);
  1362.                     vertex[1].x=(double) (x_prime[prime_num]);
  1363.                     vertex[1].y=(double) (y_prime[prime_num]);
  1364.                     vertex[1].z=(double) (z_prime[prime_num]);
  1365.                     prime_num++;
  1366.                     vertex[2].x=(double) (x_prime[prime_num]);
  1367.                     vertex[2].y=(double) (y_prime[prime_num]);
  1368.                     vertex[2].z=(double) (z_prime[prime_num]);
  1369.                     prime_num-=((long) num_y_divisions);
  1370.                     vertex[3].x=(double) (x_prime[prime_num]);
  1371.                     vertex[3].y=(double) (y_prime[prime_num]);
  1372.                     vertex[3].z=(double) (z_prime[prime_num]);
  1373.                     prime_num--;
  1374.                   }
  1375.                 else
  1376.                   {
  1377.                     prime_num--;
  1378.                     vertex[1].x=(double) (x_prime[prime_num]);
  1379.                     vertex[1].y=(double) (y_prime[prime_num]);
  1380.                     vertex[1].z=(double) (z_prime[prime_num]);
  1381.                     prime_num+=((long) num_y_divisions);
  1382.                     vertex[2].x=(double) (x_prime[prime_num]);
  1383.                     vertex[2].y=(double) (y_prime[prime_num]);
  1384.                     vertex[2].z=(double) (z_prime[prime_num]);
  1385.                     prime_num++;
  1386.                     vertex[3].x=(double) (x_prime[prime_num]);
  1387.                     vertex[3].y=(double) (y_prime[prime_num]);
  1388.                     vertex[3].z=(double) (z_prime[prime_num]);
  1389.                     prime_num-=((long) num_y_divisions);
  1390.                   }
  1391.               else
  1392.                 if (y_division_num < (num_y_divisions-1))
  1393.                   {
  1394.                     prime_num++;
  1395.                     vertex[1].x=(double) (x_prime[prime_num]);
  1396.                     vertex[1].y=(double) (y_prime[prime_num]);
  1397.                     vertex[1].z=(double) (z_prime[prime_num]);
  1398.                     prime_num-=((long) num_y_divisions);
  1399.                     vertex[2].x=(double) (x_prime[prime_num]);
  1400.                     vertex[2].y=(double) (y_prime[prime_num]);
  1401.                     vertex[2].z=(double) (z_prime[prime_num]);
  1402.                     prime_num--;
  1403.                     vertex[3].x=(double) (x_prime[prime_num]);
  1404.                     vertex[3].y=(double) (y_prime[prime_num]);
  1405.                     vertex[3].z=(double) (z_prime[prime_num]);
  1406.                     prime_num+=((long) num_y_divisions);
  1407.                   }
  1408.                 else
  1409.                   {
  1410.                     prime_num-=((long) num_y_divisions);
  1411.                     vertex[1].x=(double) (x_prime[prime_num]);
  1412.                     vertex[1].y=(double) (y_prime[prime_num]);
  1413.                     vertex[1].z=(double) (z_prime[prime_num]);
  1414.                     prime_num--;
  1415.                     vertex[2].x=(double) (x_prime[prime_num]);
  1416.                     vertex[2].y=(double) (y_prime[prime_num]);
  1417.                     vertex[2].z=(double) (z_prime[prime_num]);
  1418.                     prime_num+=((long) num_y_divisions);
  1419.                     vertex[3].x=(double) (x_prime[prime_num]);
  1420.                     vertex[3].y=(double) (y_prime[prime_num]);
  1421.                     vertex[3].z=(double) (z_prime[prime_num]);
  1422.                     prime_num++;
  1423.                   }
  1424.               normal.x
  1425.                =(vertex[1].y-vertex[0].y)*(vertex[3].z-vertex[0].z)
  1426.                -(vertex[3].y-vertex[0].y)*(vertex[1].z-vertex[0].z)
  1427.                +(vertex[2].y-vertex[1].y)*(vertex[0].z-vertex[1].z)
  1428.                -(vertex[0].y-vertex[1].y)*(vertex[2].z-vertex[1].z)
  1429.                +(vertex[3].y-vertex[2].y)*(vertex[1].z-vertex[2].z)
  1430.                -(vertex[1].y-vertex[2].y)*(vertex[3].z-vertex[2].z)
  1431.                +(vertex[0].y-vertex[3].y)*(vertex[2].z-vertex[3].z)
  1432.                -(vertex[2].y-vertex[3].y)*(vertex[0].z-vertex[3].z);
  1433.               normal.y
  1434.                =(vertex[3].x-vertex[0].x)*(vertex[1].z-vertex[0].z)
  1435.                -(vertex[1].x-vertex[0].x)*(vertex[3].z-vertex[0].z)
  1436.                +(vertex[0].x-vertex[1].x)*(vertex[2].z-vertex[1].z)
  1437.                -(vertex[2].x-vertex[1].x)*(vertex[0].z-vertex[1].z)
  1438.                +(vertex[1].x-vertex[2].x)*(vertex[3].z-vertex[2].z)
  1439.                -(vertex[3].x-vertex[2].x)*(vertex[1].z-vertex[2].z)
  1440.                +(vertex[2].x-vertex[3].x)*(vertex[0].z-vertex[3].z)
  1441.                -(vertex[0].x-vertex[3].x)*(vertex[2].z-vertex[3].z);
  1442.               normal.z
  1443.                =(vertex[1].x-vertex[0].x)*(vertex[3].y-vertex[0].y)
  1444.                -(vertex[3].x-vertex[0].x)*(vertex[1].y-vertex[0].y)
  1445.                +(vertex[2].x-vertex[1].x)*(vertex[0].y-vertex[1].y)
  1446.                -(vertex[0].x-vertex[1].x)*(vertex[2].y-vertex[1].y)
  1447.                +(vertex[3].x-vertex[2].x)*(vertex[1].y-vertex[2].y)
  1448.                -(vertex[1].x-vertex[2].x)*(vertex[3].y-vertex[2].y)
  1449.                +(vertex[0].x-vertex[3].x)*(vertex[2].y-vertex[3].y)
  1450.                -(vertex[2].x-vertex[3].x)*(vertex[0].y-vertex[3].y);
  1451.               if (normal.x < 0.0)
  1452.                 color[prime_num]=NUM_COLORS;
  1453.               else
  1454.                 {
  1455.                   magnitude
  1456.                    =sqrt(normal.x*normal.x+normal.y*normal.y+normal.z*normal.z);
  1457.                   if (magnitude == 0.0)
  1458.                     color[prime_num]=(unsigned char) 0;
  1459.                   else
  1460.                     {
  1461.                       color[prime_num]
  1462.                        =(unsigned char) ((((float) (NUM_COLORS-1))/2.0)*(1.0
  1463.                        +((*light).x*normal.x+(*light).y*normal.y
  1464.                        +(*light).z*normal.z)/magnitude));
  1465.                       if (color[prime_num] >= (unsigned char) (NUM_COLORS-1))
  1466.                         color[prime_num]=(unsigned char) (NUM_COLORS-2);
  1467.                     }
  1468.                 }
  1469.               prime_num++;
  1470.             }
  1471.         }
  1472.       return;
  1473.     }
  1474.  
  1475. static void adjust_perspective(num_x_divisions,num_y_divisions,x_prime,y_prime,
  1476.  z_prime,x_prime_max,y_prime_min,y_prime_max,z_prime_min,z_prime_max)
  1477.   int        num_x_divisions;
  1478.   int        num_y_divisions;
  1479.   float      *x_prime;
  1480.   float      *y_prime;
  1481.   float      *z_prime;
  1482.   double     x_prime_max;
  1483.   double     y_prime_min;
  1484.   double     y_prime_max;
  1485.   double     z_prime_min;
  1486.   double     z_prime_max;  
  1487.     {
  1488.       static   long       prime_num;
  1489.       static   vertex_rec vertex [4];
  1490.       register int        x_division_num;
  1491.       static   double     x_eye;
  1492.       static   double     y_center;
  1493.       register int        y_division_num;
  1494.       static   double     z_center;
  1495.  
  1496.       if ((y_prime_max-y_prime_min) > (z_prime_max-z_prime_min))
  1497.         x_eye=1.1*(y_prime_max-y_prime_min)+x_prime_max;
  1498.       else
  1499.         x_eye=1.1*(z_prime_max-z_prime_min)+x_prime_max;
  1500.       if (((y_prime_max-y_prime_min) > (z_prime_max-z_prime_min))
  1501.       ||  (z_prime_max != z_prime_min))
  1502.         {
  1503.           y_center=(y_prime_max+y_prime_min)/2.0;
  1504.           z_center=(z_prime_max+z_prime_min)/2.0;
  1505.           prime_num=0l;
  1506.           for (x_division_num=0; 
  1507.            ((! SizeMaze_kill) && (x_division_num < num_x_divisions));
  1508.            x_division_num++)
  1509.             {
  1510.               for (y_division_num=0; 
  1511.                ((! SizeMaze_kill) && (y_division_num < num_y_divisions));
  1512.                y_division_num++)
  1513.                 {
  1514.                   vertex[0].x=(double) (x_prime[prime_num]);
  1515.                   vertex[0].y=(double) (y_prime[prime_num]);
  1516.                   vertex[0].z=(double) (z_prime[prime_num]);
  1517.                   if (x_division_num < (num_x_divisions-1))
  1518.                     if (y_division_num < (num_y_divisions-1))
  1519.                       {
  1520.                         prime_num+=((long) num_y_divisions);
  1521.                         vertex[1].x=(double) (x_prime[prime_num]);
  1522.                         vertex[1].y=(double) (y_prime[prime_num]);
  1523.                         vertex[1].z=(double) (z_prime[prime_num]);
  1524.                         prime_num++;
  1525.                         vertex[2].x=(double) (x_prime[prime_num]);
  1526.                         vertex[2].y=(double) (y_prime[prime_num]);
  1527.                         vertex[2].z=(double) (z_prime[prime_num]);
  1528.                         prime_num-=((long) num_y_divisions);
  1529.                         vertex[3].x=(double) (x_prime[prime_num]);
  1530.                         vertex[3].y=(double) (y_prime[prime_num]);
  1531.                         vertex[3].z=(double) (z_prime[prime_num]);
  1532.                         prime_num--;
  1533.                       }
  1534.                     else
  1535.                       {
  1536.                         prime_num--;
  1537.                         vertex[1].x=(double) (x_prime[prime_num]);
  1538.                         vertex[1].y=(double) (y_prime[prime_num]);
  1539.                         vertex[1].z=(double) (z_prime[prime_num]);
  1540.                         prime_num+=((long) num_y_divisions);
  1541.                         vertex[2].x=(double) (x_prime[prime_num]);
  1542.                         vertex[2].y=(double) (y_prime[prime_num]);
  1543.                         vertex[2].z=(double) (z_prime[prime_num]);
  1544.                         prime_num++;
  1545.                         vertex[3].x=(double) (x_prime[prime_num]);
  1546.                         vertex[3].y=(double) (y_prime[prime_num]);
  1547.                         vertex[3].z=(double) (z_prime[prime_num]);
  1548.                         prime_num-=((long) num_y_divisions);
  1549.                       }
  1550.                   else
  1551.                     if (y_division_num < (num_y_divisions-1))
  1552.                       {
  1553.                         prime_num++;
  1554.                         vertex[1].x=(double) (x_prime[prime_num]);
  1555.                         vertex[1].y=(double) (y_prime[prime_num]);
  1556.                         vertex[1].z=(double) (z_prime[prime_num]);
  1557.                         prime_num-=((long) num_y_divisions);
  1558.                         vertex[2].x=(double) (x_prime[prime_num]);
  1559.                         vertex[2].y=(double) (y_prime[prime_num]);
  1560.                         vertex[2].z=(double) (z_prime[prime_num]);
  1561.                         prime_num--;
  1562.                         vertex[3].x=(double) (x_prime[prime_num]);
  1563.                         vertex[3].y=(double) (y_prime[prime_num]);
  1564.                         vertex[3].z=(double) (z_prime[prime_num]);
  1565.                         prime_num+=((long) num_y_divisions);
  1566.                       }
  1567.                     else
  1568.                       {
  1569.                         prime_num-=((long) num_y_divisions);
  1570.                         vertex[1].x=(double) (x_prime[prime_num]);
  1571.                         vertex[1].y=(double) (y_prime[prime_num]);
  1572.                         vertex[1].z=(double) (z_prime[prime_num]);
  1573.                         prime_num--;
  1574.                         vertex[2].x=(double) (x_prime[prime_num]);
  1575.                         vertex[2].y=(double) (y_prime[prime_num]);
  1576.                         vertex[2].z=(double) (z_prime[prime_num]);
  1577.                         prime_num+=((long) num_y_divisions);
  1578.                         vertex[3].x=(double) (x_prime[prime_num]);
  1579.                         vertex[3].y=(double) (y_prime[prime_num]);
  1580.                         vertex[3].z=(double) (z_prime[prime_num]);
  1581.                         prime_num++;
  1582.                       }
  1583.                   y_prime[prime_num]=(float) y_center
  1584.                    +(vertex[0].y-y_center)*(x_eye-x_prime_max)
  1585.                    /(x_eye-vertex[0].x);
  1586.                   z_prime[prime_num]=(float) z_center
  1587.                    +(vertex[0].z-z_center)*(x_eye-x_prime_max)
  1588.                    /(x_eye-vertex[0].x);
  1589.                   x_prime[prime_num]=(float)
  1590.                    (-(vertex[0].x+vertex[1].x+vertex[2].x+vertex[3].x)/4.0);
  1591.                   prime_num++;
  1592.                 }
  1593.             }
  1594.          }
  1595.       return;
  1596.     }
  1597.  
  1598. static void sort_back_to_front(num_primes,x_prime,x_division_index,
  1599.  y_division_index)
  1600.   long       num_primes;
  1601.   float      *x_prime;
  1602.   int        *x_division_index;
  1603.   int        *y_division_index;
  1604.     {
  1605.       static   int   finished;
  1606.       static   long  key_index_1;
  1607.       static   long  key_index_2;
  1608.       static   long  left;
  1609.       static   long  right;
  1610.       static   float t1;
  1611.       register int   t2;
  1612.       register int   t3;
  1613.  
  1614.       left=num_primes/((long) 2);
  1615.       right=num_primes-1l;
  1616.       t1=x_prime[0];
  1617.       t2=x_division_index[0];
  1618.       t3=y_division_index[0];
  1619.       while ((! SizeMaze_kill) && (right > 0l))
  1620.         {
  1621.           if (left > 0l)
  1622.             {
  1623.               left--;
  1624.               t1=x_prime[left];
  1625.               t2=x_division_index[left];
  1626.               t3=y_division_index[left];
  1627.             }
  1628.           else
  1629.             {
  1630.               t1=x_prime[right];
  1631.               t2=x_division_index[right];
  1632.               t3=y_division_index[right];
  1633.               x_prime[right]=x_prime[0];
  1634.               x_division_index[right]=x_division_index[0];
  1635.               y_division_index[right]=y_division_index[0];
  1636.               right--;
  1637.             }
  1638.           if (right > 0l)
  1639.             {
  1640.               finished=FALSE;
  1641.               key_index_2=left;
  1642.               while (! finished)
  1643.                 {
  1644.                   key_index_1=key_index_2;
  1645.                   key_index_2+=key_index_2;
  1646.                   key_index_2++;
  1647.                   if (key_index_2 > right)
  1648.                     finished=TRUE;
  1649.                   else
  1650.                     {
  1651.                       if (key_index_2 != right)
  1652.                         {
  1653.                           if (x_prime[key_index_2] > x_prime[key_index_2+1])
  1654.                             key_index_2++;
  1655.                         }
  1656.                       if (t1 <= x_prime[key_index_2])
  1657.                         finished=TRUE;
  1658.                       else
  1659.                         {
  1660.                           x_prime[key_index_1]=x_prime[key_index_2];
  1661.                           x_division_index[key_index_1]
  1662.                            =x_division_index[key_index_2];
  1663.                           y_division_index[key_index_1]
  1664.                            =y_division_index[key_index_2];
  1665.                         }
  1666.                     }
  1667.                 }
  1668.               x_prime[key_index_1]=t1;
  1669.               x_division_index[key_index_1]=t2;
  1670.               y_division_index[key_index_1]=t3;
  1671.             }
  1672.         }
  1673.       x_prime[0]=t1;
  1674.       x_division_index[0]=t2;
  1675.       y_division_index[0]=t3;
  1676.       return;
  1677.     }
  1678.  
  1679. static void plot(arg)
  1680.   ULONG arg;
  1681.     {  
  1682.       static   POINTL        box [4];
  1683.       static   int           box_num;
  1684.       static   short         color_num;
  1685.       static   double        pixels_per_unit;
  1686.       static   long          prime_num;
  1687.                POINTL        ptlPosition;
  1688.       static   long          rgb [NUM_COLORS];
  1689.       static   long          rgb_increment;
  1690.       static   int           solution;
  1691.       static   long          tint;
  1692.       static   vertex_rec    vertex [4];
  1693.       static   int           x_division_num;
  1694.       static   long          x_prime_num;
  1695.       static   int           y_division_num;
  1696.       static   double        y_offset;
  1697.       static   double        y_out_max;
  1698.       static   double        z_offset;
  1699.       static   double        z_out_max;
  1700.  
  1701.       DosWaitEventSem((HEV) SizeMaze_active,(ULONG) SEM_INDEFINITE_WAIT);
  1702.       if ((! plot_kill) && (iFatalError))
  1703.         {
  1704.           GpiSetColor(hPS,ERROR_COLOR);
  1705.           ptlPosition.x=0;
  1706.           ptlPosition.y=0;
  1707.           GpiMove(hPS,&ptlPosition);
  1708.           ptlPosition.x=iMaxX;
  1709.           ptlPosition.y=iMaxY;
  1710.           GpiBox(hPS,DRO_FILL,&ptlPosition,(long) 0,(long) 0);
  1711.           DosBeep(60,333);
  1712.         }
  1713.       else
  1714.         {
  1715.           if (! plot_kill)
  1716.             {
  1717.               if ((solve_draw_or_clear == ((int) 'D')) 
  1718.               ||  (solve_draw_or_clear == ((int) 'B')))
  1719.                 GpiErase(hPS);
  1720.               rgb_increment=0x111111;
  1721.               tint=0l;
  1722.               for (color_num=0; color_num < (NUM_COLORS-1); color_num++)
  1723.                 {
  1724.                   rgb[color_num]=tint;
  1725.                   tint+=rgb_increment;
  1726.                 }
  1727.               rgb[NUM_COLORS-1]=0xff0000;
  1728.               GpiCreateLogColorTable(hPS,LCOL_RESET,LCOLF_CONSECRGB,0L,16L,
  1729.                &rgb[0]);
  1730.             }
  1731.           if (! plot_kill)
  1732.             {
  1733.               y_out_max=(double) iMaxX;
  1734.               z_out_max=(double) iMaxY;
  1735.               if (aspect_ratio*z_out_max*(y_prime_max-y_prime_min)
  1736.                > y_out_max*(z_prime_max-z_prime_min))
  1737.                 {
  1738.                   pixels_per_unit
  1739.                    =y_out_max/(aspect_ratio*(y_prime_max-y_prime_min));
  1740.                   y_offset=0.0;
  1741.                   z_offset
  1742.                    =(z_out_max-pixels_per_unit*(z_prime_max-z_prime_min))/2.0;
  1743.                 }
  1744.               else
  1745.                 if (aspect_ratio*z_out_max*(y_prime_max-y_prime_min)
  1746.                  < y_out_max*(z_prime_max-z_prime_min))
  1747.                   {
  1748.                     pixels_per_unit=z_out_max/(z_prime_max-z_prime_min);
  1749.                     y_offset=(y_out_max
  1750.                      -aspect_ratio*pixels_per_unit*(y_prime_max-y_prime_min))/2.0;
  1751.                     z_offset=0.0;
  1752.                   }
  1753.                 else
  1754.                   {
  1755.                     pixels_per_unit=1.0;
  1756.                     y_offset=y_out_max/2.0;
  1757.                     z_offset=z_out_max/2.0;
  1758.                   }
  1759.             }
  1760.           for (x_prime_num=0l; ((! plot_kill) && (x_prime_num < num_primes));
  1761.            x_prime_num++)
  1762.             {
  1763.               x_division_num=x_division_index[x_prime_num];
  1764.               if (x_division_num < (num_x_divisions-1))
  1765.                 {
  1766.                   y_division_num=y_division_index[x_prime_num];
  1767.                   if (y_division_num < (num_y_divisions-1))
  1768.                     {
  1769.                       prime_num
  1770.                        =((long) num_y_divisions)*((long) x_division_num)
  1771.                        +((long) y_division_num);
  1772.                       color_num=(short) (color[prime_num]);
  1773.                       if (color_num < NUM_COLORS)
  1774.                         {
  1775.                           vertex[0].y=(double) (y_prime[prime_num]);
  1776.                           vertex[0].z=(double) (z_prime[prime_num]);
  1777.                           solution=(base_z[prime_num] == (unsigned char) 2);
  1778.                           prime_num+=((long) num_y_divisions);
  1779.                           vertex[1].y=(double) (y_prime[prime_num]);
  1780.                           vertex[1].z=(double) (z_prime[prime_num]);
  1781.                           if (solution)
  1782.                             solution=(base_z[prime_num] == (unsigned char) 2);
  1783.                           prime_num++;
  1784.                           vertex[2].y=(double) (y_prime[prime_num]);
  1785.                           vertex[2].z=(double) (z_prime[prime_num]);
  1786.                           if (solution)
  1787.                             solution=(base_z[prime_num] == (unsigned char) 2);
  1788.                           prime_num-=((long) num_y_divisions);
  1789.                           vertex[3].y=(double) (y_prime[prime_num]);
  1790.                           vertex[3].z=(double) (z_prime[prime_num]);
  1791.                           if (solution)
  1792.                             solution=(base_z[prime_num] == (unsigned char) 2);
  1793.                           if ((solve_draw_or_clear == ((int) 'D')) 
  1794.                           ||  (solve_draw_or_clear == ((int) 'B'))
  1795.                           ||  ((solve_draw_or_clear == ((int) 'S'))
  1796.                             && (solution))
  1797.                           ||  ((solve_draw_or_clear == ((int) 'C'))
  1798.                             && (solution)))
  1799.                             {
  1800.                               if ((solve_draw_or_clear == ((int) 'S'))
  1801.                               ||  ((solve_draw_or_clear == ((int) 'B'))
  1802.                                 && (solution)))
  1803.                                 color_num=(short) (NUM_COLORS-1);
  1804.                               for (box_num=0; box_num < 4; box_num++)
  1805.                                 {
  1806.                                   box[box_num].x=(long) (y_offset
  1807.                                    +pixels_per_unit*aspect_ratio
  1808.                                    *(vertex[box_num].y-y_prime_min));
  1809.                                   box[box_num].y=(long) (z_offset
  1810.                                    +pixels_per_unit
  1811.                                    *(vertex[box_num].z-z_prime_min));
  1812.                                 }
  1813.                               GpiBeginPath(hPS,1L);
  1814.                               ptlPosition.x=box[3].x;
  1815.                               ptlPosition.y=box[3].y;
  1816.                               GpiMove(hPS,&ptlPosition);
  1817.                               GpiPolyLine(hPS,4l,box);
  1818.                               GpiEndPath(hPS);
  1819.                               GpiSetColor(hPS,color_num);
  1820.                               GpiFillPath(hPS,1l,FPATH_ALTERNATE);
  1821.                             }
  1822.                         }
  1823.                     }
  1824.                 }
  1825.             }
  1826.         }
  1827.       DosEnterCritSec();
  1828.       if (! plot_kill)
  1829.         WinPostMsg(plot_hwnd,(ULONG) WM_PLOT_DONE,(MPARAM) NULL,
  1830.          (MPARAM) NULL);
  1831.       DosPostEventSem((HEV) plot_active);
  1832.       return;
  1833.     }
  1834.  
  1835. static void DestroyMaze(x_prime,y_prime,z_prime,x_division_index,
  1836.  y_division_index,color,base_z,stack)
  1837.   float              **x_prime;
  1838.   float              **y_prime;
  1839.   float              **z_prime;
  1840.   int                **x_division_index;
  1841.   int                **y_division_index;
  1842.   unsigned char      **color;
  1843.   unsigned char      **base_z;
  1844.   stack_rec          **stack;
  1845.     {
  1846.       static   int y;
  1847.  
  1848.       if (*stack != (stack_rec *) NULL)
  1849.         {
  1850.           free((void *) *stack);
  1851.           *stack=(stack_rec *) NULL;
  1852.         }
  1853.       if (*base_z != (unsigned char *) NULL)
  1854.         {
  1855.           free((void *) *base_z);
  1856.           *base_z=(unsigned char *) NULL;
  1857.         }
  1858.       if (*color != (unsigned char *) NULL)
  1859.         {
  1860.           free((void *) *color);
  1861.           *color=(unsigned char *) NULL;
  1862.         }
  1863.       if (*y_division_index != (int *) NULL)
  1864.         {
  1865.           free((void *) *y_division_index);
  1866.           *y_division_index=(int *) NULL;
  1867.         }
  1868.       if (*x_division_index != (int *) NULL)
  1869.         {
  1870.           free((void *) *x_division_index);
  1871.           *x_division_index=(int *) NULL;
  1872.         }
  1873.       if (*z_prime != (float *) NULL)
  1874.         {
  1875.           free((void *) *z_prime);
  1876.           *z_prime=(float *) NULL;
  1877.         }
  1878.       if (*y_prime != (float *) NULL)
  1879.         {
  1880.           free((void *) *y_prime);
  1881.           *y_prime=(float *) NULL;
  1882.         }
  1883.       if (*x_prime != (float *) NULL)
  1884.         {
  1885.           free((void *) *x_prime);
  1886.           *x_prime=(float *) NULL;
  1887.         }
  1888.       if (page != (char **) NULL)
  1889.         {
  1890.           for (y=0; y < max_y_plus_1; y++)
  1891.             free((void *) (page[y]));
  1892.           free((void *) page);
  1893.           page=(char **) NULL;
  1894.         }
  1895.       return;
  1896.     }
  1897.  
  1898. static double f(x,y)
  1899.   double x;
  1900.   double y;
  1901.     {
  1902.       static   int    solution;
  1903.       register int    x_next;
  1904.       static   int    x_offset;
  1905.       static   int    x_out;
  1906.       static   int    y_next;
  1907.       register int    y_offset;
  1908.       static   int    y_out;
  1909.       static   double z;
  1910.  
  1911.       y_next=(int) x;
  1912.       y_out=y_next+RESOLUTION;
  1913.       y_out-=2;
  1914.       y_out/=RESOLUTION;
  1915.       y_out--;
  1916.       if ((y_out%2 == 0)
  1917.       &&  (2*((y_next+RESOLUTION-2)-(RESOLUTION*(y_out+1)))
  1918.        > RESOLUTION))
  1919.         y_out++;
  1920.       if (y_out < 0)
  1921.         z=0.0;
  1922.       else
  1923.         if (y_out > max_y)
  1924.           z=0.0;
  1925.         else
  1926.           {
  1927.             x_next=(int) y;
  1928.             x_out=x_next+RESOLUTION;
  1929.             x_out-=2;
  1930.             x_out/=RESOLUTION;
  1931.             x_out--;
  1932.             if ((x_out%2 == 0)
  1933.             &&  (2*((x_next+RESOLUTION-2)-(RESOLUTION*(x_out+1)))
  1934.              > RESOLUTION))
  1935.               x_out++;
  1936.             if (x_out < 0)
  1937.               z=0.0;
  1938.             else
  1939.               if (x_out > max_x)
  1940.                 z=0.0;
  1941.               else
  1942.                 if (page[y_out][x_out] == 'W')
  1943.                   {
  1944.                     solution=FALSE;
  1945.                     for (x_offset=-1; x_offset <= 1; x_offset++)
  1946.                       for (y_offset=-1; y_offset <= 1; y_offset++)
  1947.                         if (x_offset != 0)
  1948.                           {
  1949.                             x_next=x_out+x_offset;
  1950.                             y_next=y_out+y_offset;
  1951.                             if ((x_next >= 0)
  1952.                             &&  (x_next <= max_x)
  1953.                             &&  (y_next >= 0)
  1954.                             &&  (y_next <= max_y)
  1955.                             &&  (page[y_next][x_next] == 'S'))
  1956.                               solution=TRUE;
  1957.                           }
  1958.                         else
  1959.                           {
  1960.                             if (y_offset != 0)
  1961.                               {
  1962.                                 x_next=x_out+x_offset;
  1963.                                 y_next=y_out+y_offset;
  1964.                                 if ((x_next >= 0)
  1965.                                 &&  (x_next <= max_x)
  1966.                                 &&  (y_next >= 0)
  1967.                                 &&  (y_next <= max_y)
  1968.                                 &&  (page[y_next][x_next] == 'S'))
  1969.                                   solution=TRUE;
  1970.                               }
  1971.                           };
  1972.                     z=4.0*((double) RESOLUTION);
  1973.                     if (solution)
  1974.                       z=-z;
  1975.                   }
  1976.                 else
  1977.                   z=0.0;
  1978.           }
  1979.       return(z);
  1980.     }
  1981.  
  1982.