home *** CD-ROM | disk | FTP | other *** search
/ The Fred Fish Collection 1.5 / ffcollection-1-5-1992-11.iso / ff_disks / 300-399 / ff304.lzh / Gears / gears.c < prev    next >
C/C++ Source or Header  |  1990-01-10  |  17KB  |  776 lines

  1. /*
  2.  *  GEARS : Bicycle gear ratio Calculator
  3.  *
  4.  *    Version 1
  5.  *
  6.  *    by Joel Swank 9-19-89
  7.  *
  8.  */
  9.  
  10. /********* INCLUDES ************************ */
  11.  
  12.  
  13. #include <exec/types.h>
  14. #include <exec/io.h>
  15. #include <exec/memory.h>
  16. #include <libraries/dos.h>
  17. #include <intuition/intuition.h>
  18. #include <stdio.h>
  19. #include "fio.h"
  20.  
  21.  
  22. /* Data in helpwin.h  */
  23. extern struct IntuiText prfailtxt ;
  24. extern struct IntuiText badfiletxt ;
  25. extern struct IntuiText fiofailtxt ;
  26. extern struct IntuiText winfailtxt ;
  27. extern struct IntuiText lockfailtxt ;
  28. extern struct IntuiText geartxt ;
  29. extern struct IntuiText infailtxt ;
  30. extern struct IntuiText infailtxt2 ;
  31. extern struct IntuiText oktxt ;
  32. extern struct IntuiText cantxt ;
  33. extern struct IntuiText retrytxt ;
  34. extern struct NewWindow    NewWindowStructureHelp;
  35. extern struct NewWindow    NewWindowStructure3;
  36. extern char gear_buff[];
  37.  
  38. /* Data in doargs.c   */
  39. extern char filename[];
  40.  
  41. /* Defines for setting/clearing GADGDISABLED flag */
  42. #define OffGad(gad) (gad).Flags = gad.Flags | GADGDISABLED
  43. #define OnGad(gad) (gad).Flags = gad.Flags & ~(GADGDISABLED)
  44. #define OffMenu(item) (item).Flags = item.Flags & ~(CHECKED)
  45. #define OnMenu(item) (item).Flags = item.Flags | CHECKED
  46.  
  47.  
  48.  
  49. extern struct IntuitionBase *IntuitionBase ;
  50. extern struct GfxBase *GfxBase ;
  51. extern struct DosLibrary *DosBase ;
  52.  
  53. struct Screen *OpenScreen();
  54. struct Screen *Sc = NULL;
  55. struct ViewPort vP;
  56. struct Window *wG = NULL;
  57. struct Window *wF = NULL;
  58. struct RastPort *rpG;
  59. struct IntuiMessage *message;    /* the message from the IDCMP */
  60.  
  61. struct Window *OpenWindow();
  62. void *OpenLibrary();
  63. struct IntuiMessage *GetMsg();
  64. struct MenuItem *ItemAddress();
  65.  
  66. struct FileIOSupport *FIOSupp = NULL;      /* fileio support stuff */
  67. struct FileIOSupport *GetFileIOSupport();
  68. struct FileLock *Lock();
  69. char save_title[] = "Select File to SAVE";
  70. char load_title[] = "Select File to LOAD";
  71.  
  72. /* get the PowerWindows 2.0 code */
  73. #include "gearscreen.h"
  74.  
  75. /* internal data areas */
  76. int front = 2;      /* number of front gears */
  77. int rear = 6;       /* number of rear gears */
  78. float ratios[21];   /* storage for ratios    */
  79. float front_gear[3];/* storage for front gears */
  80. float rear_gear[7]; /* storage for rear gears */
  81. int av[21];         /* indices for sort      */
  82. char cbuf[21][8];   /* storage for gear combos */
  83. int count = 0;      /* count of ratios        */
  84. int diameter = 27;  /* wheel diameter from args */
  85. long color[8];    /* savearea for colors  */
  86. struct ColorMap *cm; /* pointer to screen colors */
  87. char rearmsg[] = "Bad Rear Gear: ";
  88. char frontmsg[] = "Bad Front Gear: ";
  89.  
  90.  
  91. main(argc,argv)
  92. int argc;
  93. char *argv[];
  94. {
  95.     UWORD code;
  96.     ULONG class;
  97.     APTR object;
  98.     FILE *fp;
  99.  
  100.  
  101.     /* Open the libraries */
  102.  
  103.     IntuitionBase = (struct IntuitionBase *)
  104.         OpenLibrary("intuition.library", 0L);
  105.     if (IntuitionBase == NULL)
  106.         {
  107.         done(11);
  108.         }
  109.     GfxBase = (struct GfxBase *)OpenLibrary("graphics.library", 0L);
  110.     if (GfxBase == NULL)
  111.         {
  112.         done(10);
  113.         }
  114.  
  115.     DosBase = (struct DosLibrary *)OpenLibrary("dos.library", 0);
  116.     if (DosBase == NULL)
  117.         {
  118.         done(16);
  119.         }
  120.  
  121.     /*   Get the arguments */
  122.  
  123.     filename[0] = '\0';
  124.     if (argc == 0) getWBargs();
  125.     else getCLIargs(argc,argv);
  126.     Diameter_GadSInfo.LongInt = diameter;
  127.     sprintf(Diameter_GadSIBuff,"%d",diameter);
  128.  
  129.     /* Open my screen      */
  130.  
  131.     Sc = OpenScreen(&NewScreenStructure);
  132.     if ( Sc == NULL )
  133.         {
  134.         done(15);
  135.         }
  136.     vP = Sc->ViewPort;
  137.     LoadRGB4(&vP,&Palette,PaletteColorCount);
  138.  
  139.     /* tie windows to my screen */
  140.  
  141.     NewWindowStructureHelp.Screen = Sc;
  142.     NewWindowStructure3.Screen = Sc;
  143.     NewWindowStructure1.Screen = Sc;
  144.  
  145.     wG = OpenWindow(&NewWindowStructure1);    /* open main window */
  146.     if ( wG == NULL )
  147.         {
  148.         done(12);
  149.         }
  150.  
  151.     rpG = wG->RPort;    /* get a rastport pointer for the window */
  152.  
  153.     PrintIText(rpG,&IntuiTextList1,0L,0L); /* write window text */
  154.  
  155.     SetMenuStrip(wG,&MenuList1);    /* attach my Menu */
  156.  
  157.     if (filename[0] != '\0')
  158.         {
  159.         while ((fp = fopen(filename,"r")) == NULL)
  160.             {
  161.             infailtxt2.IText = (UBYTE *) filename;
  162.             if (AutoRequest(wG,&infailtxt,&retrytxt,&cantxt,
  163.                 0L,0L,reqlen(filename),75L)) continue;
  164.             }
  165.         if (fp != NULL) {
  166.             read_file(fp);
  167.             fclose(fp);
  168.             }
  169.         }
  170.  
  171.     /* Wait for some User interaction */
  172.     while(1)
  173.     {
  174.         WaitPort(wG->UserPort);
  175.             while( (message = (struct IntuiMessage *)
  176.                 GetMsg(wG->UserPort) ) != NULL)
  177.             {
  178.                 code = message->Code;  /* MENUNUM */
  179.                 object = message->IAddress;  /* Gadget */
  180.                 class = message->Class;  /* IDCMP Flags */
  181.                 ReplyMsg(message);  /* Free the sender */
  182.                 switch (class)
  183.                     {
  184.                     case CLOSEWINDOW :
  185.                         done(0);   /* close gadget clicked */
  186.                     case GADGETUP:
  187.                         if (object == (APTR) &Calc_Gad)
  188.                             {
  189.                             calc_it();
  190.                             display_it();
  191.                             break;
  192.                             }
  193.                         /* add more gadget checks here */
  194.                         break;
  195.                     case MENUPICK:    /* menu selection made */
  196.                         /* I get a NULL message whenever the user brings
  197.                            up the menu but doesn't select anything    */
  198.                         if (code != MENUNULL) do_pick((USHORT)code);
  199.                         break;
  200.                     }
  201.             }
  202.     } 
  203. }
  204.  
  205. /*
  206.  * Cleanup and exit
  207.  */
  208.  
  209. done(how)
  210. int how;
  211. {
  212.     if (FIOSupp) ReleaseFileIO(FIOSupp);
  213.     if (wG) ClearMenuStrip(wG);
  214.     if (wG) CloseWindow(wG);
  215.     if (Sc) CloseScreen(Sc);
  216.     if (DosBase) CloseLibrary(DosBase);
  217.     if (GfxBase != NULL) CloseLibrary(GfxBase);
  218.     if (IntuitionBase != NULL) CloseLibrary(IntuitionBase);
  219.     exit(how);
  220.  
  221.  /* exit codes 
  222.   * 0  User requested
  223.   * 10 graphics lib open fail
  224.   * 11 intuition lib open fail
  225.   * 12 main window open fail
  226.   * 13 _abort() called
  227.   * 14 Bad CLI args
  228.   * 15 Custom Screen open Fail
  229.   * 16 Dos lib open fail
  230.   */
  231. }
  232.  
  233.  
  234. /*
  235.  * do_pick : handle chain of menu selections
  236.  */
  237.  
  238. do_pick(menunum)
  239. USHORT menunum;
  240. {
  241. struct MenuItem *item, *ItemAddress();
  242.     while (menunum != MENUNULL)
  243.         {
  244.         switch(MENUNUM(menunum))
  245.             {
  246.             case 0:     /* Project Menu */
  247.             switch(ITEMNUM(menunum))
  248.                 {
  249.                 case 0: /* Load */
  250.                     do_load();
  251.                     break;
  252.                 case 1: /* Save */
  253.                     do_save();
  254.                     break;
  255.                 case 2: /* Print */
  256.                     do_print();
  257.                     break;
  258.                 case 3: /* Colors */
  259.                     ClearMenuStrip(wG);
  260.                     DoColorWindow(Sc,170,15,0,TRUE);
  261.                     SetMenuStrip(wG,&MenuList1);    /* re-attach my Menu */
  262.                     break;
  263.                 case 4: /* Help */
  264.                     help();
  265.                     break;
  266.                 case 5: /* About */
  267.                     about();
  268.                     break;
  269.                 case 6: /* Quit */
  270.                     done(0);
  271.                 }
  272.             break;
  273.             case 1:     /* Gears Menu */
  274.             switch(ITEMNUM(menunum))
  275.                 {
  276.                 case 0:     /* Front Gear selection */
  277.  
  278.                 /* Three mutually excluded items. intuition keeps track, 
  279.                    I have to enable/disable integer input gadgets and
  280.                    redraw the window         */
  281.  
  282.                 switch(SUBNUM(menunum))
  283.                     {
  284.                     case 0:   /* 1 */
  285.                         front = 1;
  286.                         break;
  287.                     case 1:   /* 2 */
  288.                         front = 2;
  289.                         break;
  290.                     case 2:   /* 3 */
  291.                         front = 3;
  292.                         break;
  293.                     }
  294.                 break;
  295.                 case 1:     /* Rear Gear selection */
  296.  
  297.                 /* Five mutually excluded items. intuition keeps track, 
  298.                    I have to enable/disable integer input gadgets and
  299.                    redraw the window         */
  300.  
  301.                 switch(SUBNUM(menunum))
  302.                     {
  303.                     case 0:   /* 3 */
  304.                         rear = 3;
  305.                         break;
  306.                     case 1:   /* 4 */
  307.                         rear = 4;
  308.                         break;
  309.                     case 2:   /* 5 */
  310.                         rear = 5;
  311.                         break;
  312.                     case 3:   /* 6 */
  313.                         rear = 6;
  314.                         break;
  315.                     case 4:   /* 7 */
  316.                         rear = 7;
  317.                         break;
  318.                     }
  319.                 break;
  320.                 }
  321.             set_gads();
  322.             redraw_scr();
  323.             break;
  324.             default:    /* What's this garbage ? */
  325.                 menunum = MENUNULL;
  326.             }       /* end switch MENUNUM  */
  327.  
  328.         /* Get chain to next selection. NextSelect contains another item
  329.            when the user makes multiple menu selections             */
  330.         item = ItemAddress(&MenuList1,(long) menunum);
  331.         menunum = item->NextSelect;
  332.         }
  333. }
  334.  
  335.  
  336. /*
  337.  *  Calculate and display gear table
  338.  */
  339.  
  340. calc_it()
  341. {
  342.     int i,j;
  343.     if (!check_gears()) return; /* validate the gears */
  344.  
  345.     count = 0;                 /* Calculate the ratios */
  346.     for (i=0; i<front; i++)
  347.         {
  348.         for (j=0; j<rear; j++)
  349.             {
  350.             ratios[count] = front_gear[i]/rear_gear[j]
  351.                     * Diameter_GadSInfo.LongInt;
  352.             sprintf(cbuf[count],"%2.0fx%2.0f", front_gear[i], rear_gear[j]);
  353.             count++;
  354.             }
  355.         }
  356.  
  357.     for (i=0; i<21; i++) av[i] = i; /* init index array */
  358.     QuickSort(av, count);           /* sort the indices */
  359. }
  360.  
  361.  
  362. /*
  363.  * check_gears : validate reasonable values for all active gears
  364.  */
  365.  
  366. check_gears()
  367. {
  368.     int i;
  369.  
  370.     /* capture all gear values from string gadgets */
  371.     front_gear[0] = Front1_GadSInfo.LongInt;
  372.     front_gear[1] = Front2_GadSInfo.LongInt;
  373.     front_gear[2] = Front3_GadSInfo.LongInt;
  374.     rear_gear[0] = Rear1_GadSInfo.LongInt;
  375.     rear_gear[1] = Rear2_GadSInfo.LongInt;
  376.     rear_gear[2] = Rear3_GadSInfo.LongInt;
  377.     rear_gear[3] = Rear4_GadSInfo.LongInt;
  378.     rear_gear[4] = Rear5_GadSInfo.LongInt;
  379.     rear_gear[5] = Rear6_GadSInfo.LongInt;
  380.     rear_gear[6] = Rear7_GadSInfo.LongInt;
  381.  
  382.     for (i=0;i<rear;i++)
  383.         if (rear_gear[i] < 10.0 || rear_gear[i] > 40.0)
  384.             {
  385.             sprintf(gear_buff,"%s%2.0f",rearmsg,rear_gear[i]);
  386.             AutoRequest(wG,&geartxt,0L,&oktxt,0L,0L,300L,75L);
  387.             return(FALSE);
  388.             }
  389.     for (i=0;i<front;i++)
  390.         if (front_gear[i] < 10.0 || front_gear[i] > 80.0)
  391.             {
  392.             sprintf(gear_buff,"%s%2.0f",frontmsg,front_gear[i]);
  393.             AutoRequest(wG,&geartxt,0L,&oktxt,0L,0L,300L,75L);
  394.             return(FALSE);
  395.             }
  396.     return(TRUE);
  397. }
  398.  
  399. /*
  400.  *   Set Disabled bit on all gear string gadgets 
  401.  */
  402.  
  403. set_gads()
  404. {
  405.     if (front > 1) OnGad(Front2_Gad);
  406.     else OffGad(Front2_Gad);
  407.     if (front > 2) OnGad(Front3_Gad);
  408.     else OffGad(Front3_Gad);
  409.     if (rear > 3) OnGad(Rear4_Gad);
  410.     else OffGad(Rear4_Gad);
  411.     if (rear > 4) OnGad(Rear5_Gad);
  412.     else OffGad(Rear5_Gad);
  413.     if (rear > 5) OnGad(Rear6_Gad);
  414.     else OffGad(Rear6_Gad);
  415.     if (rear > 6) OnGad(Rear7_Gad);
  416.     else OffGad(Rear7_Gad);
  417. }
  418.  
  419. /*
  420.  *   Set the menus according to front and rear
  421.  */
  422.  
  423. set_menus()
  424. {
  425.     if (rear == 3) OnMenu(SubItem1);
  426.     else OffMenu(SubItem1);
  427.     if (rear == 4) OnMenu(SubItem2);
  428.     else OffMenu(SubItem2);
  429.     if (rear == 5) OnMenu(SubItem3);
  430.     else OffMenu(SubItem3);
  431.     if (rear == 6) OnMenu(SubItem4);
  432.     else OffMenu(SubItem4);
  433.     if (rear == 7) OnMenu(SubItem5);
  434.     else OffMenu(SubItem5);
  435.     if (front == 1) OnMenu(SubItem6);
  436.     else OffMenu(SubItem6);
  437.     if (front == 2) OnMenu(SubItem7);
  438.     else OffMenu(SubItem7);
  439.     if (front == 3) OnMenu(SubItem8);
  440.     else OffMenu(SubItem8);
  441. }
  442.  
  443. /*
  444.  *    Display ratios in main window
  445.  *    (Assumes calc_it has been done)
  446.  */
  447.  
  448. #define XPOS 170
  449. #define LINESIZE 9
  450.  
  451. char header[] = "Gear  Wheel Size        Spacing";
  452. char disp_buff[100], temp_buff[30];
  453.  
  454. display_it()
  455. {
  456.     int ypos = 20, i, j;
  457.  
  458.     SetAPen(rpG,7L);  /* set draw color */
  459.     Move(rpG,XPOS,ypos);
  460.     Text(rpG,header,sizeof(header)-1);
  461.     ypos += LINESIZE;
  462.     for (i=0; i<count; i++, ypos += LINESIZE)
  463.         {
  464.         bld_buf(i);
  465.         Move(rpG,XPOS,ypos);
  466.         Text(rpG,disp_buff,strlen(disp_buff));
  467.         }
  468. }
  469.  
  470. /*
  471.  *    Print the table
  472.  */
  473.  
  474. do_print()
  475. {
  476.     int i;
  477.     FILE *fp;
  478.  
  479.     while ((fp = fopen("PRT:","w")) == NULL)
  480.         {
  481.         if (AutoRequest(wG,&prfailtxt,&retrytxt,&cantxt,
  482.             0L,0L,300L,75L)) continue;
  483.         return;
  484.         }
  485.  
  486.     fprintf(fp,"%s\n",header);
  487.  
  488.     for (i=0; i<count; i++)
  489.         {
  490.         bld_buf(i);
  491.         fprintf(fp,"%s\n",disp_buff);
  492.         }
  493.     fclose(fp);
  494. }
  495.  
  496. /*
  497.  *    Build a line of print
  498.  */
  499.  
  500. bld_buf(i)
  501. int i;
  502. {
  503.         int j;
  504.  
  505.         j = av[i];
  506.         sprintf(disp_buff,"%s   %7.2f",cbuf[j],ratios[j]);
  507.         if (i>0) {
  508.             sprintf(temp_buff,"     %6.2f",ratios[j] - ratios[av[i-1]]);
  509.             strcat(disp_buff,temp_buff);
  510.             }
  511.         if (i>1) {
  512.             sprintf(temp_buff,"     %6.2f",ratios[j] - ratios[av[i-2]]);
  513.             strcat(disp_buff,temp_buff);
  514.             }
  515.         if (i>2) {
  516.             sprintf(temp_buff,"     %6.2f",ratios[j] - ratios[av[i-3]]);
  517.             strcat(disp_buff,temp_buff);
  518.             }
  519. }
  520.  
  521. /*
  522.  *    Load data from an ASCII file
  523.  */
  524.  
  525. do_load()
  526. {
  527.     FILE *fp;
  528.  
  529.     select_file(0);
  530.     if (filename[0] == '\0') return;
  531.  
  532.     while ((fp = fopen(filename,"r")) == NULL)
  533.         {
  534.         infailtxt2.IText = (UBYTE *) filename;
  535.         if (AutoRequest(wG,&infailtxt,&retrytxt,&cantxt,
  536.             0L,0L,reqlen(filename),75L)) continue;
  537.         return;
  538.         }
  539.     read_file(fp);
  540.     fclose(fp);
  541. }
  542.  
  543.  
  544. /*
  545.  *    Read in data from open file
  546.  */
  547.  
  548. read_file(fp)
  549. FILE *fp;
  550. {
  551.     int i;
  552.     char x;
  553.     int fr = front;
  554.     int re = rear;
  555.  
  556.     i = fscanf(fp,"%d, %d",&front,&rear);
  557.     if (i != 2 || rear < 3 || rear >7 || front < 1 || front >3)
  558.         {
  559.         infailtxt2.IText = (UBYTE *) filename;
  560.         AutoRequest(wG,&badfiletxt,0L,&oktxt,0L,0L,reqlen(filename),75L);
  561.         front = fr;
  562.         rear = re;
  563.         return(FALSE);
  564.         }
  565.     fscanf(fp,", %d ,",&Diameter_GadSInfo.LongInt);
  566.     sprintf(Diameter_GadSIBuff,"%d",Diameter_GadSInfo.LongInt);
  567.     fscanf(fp,"%c",&x);
  568.     if (x == 'm') inmm_Gad.Flags |= SELECTED;
  569.     if (x == 'i') inmm_Gad.Flags &= ~SELECTED;
  570.     for (i=0;i<front;i++) fscanf(fp,",%2f",&front_gear[i]);
  571.     for (i=0;i<rear;i++) fscanf(fp,",%2f",&rear_gear[i]);
  572.  
  573.     /*   Put the data in the string gadgets */
  574.     Front1_GadSInfo.LongInt = (long) front_gear[0];
  575.     sprintf(Front1_GadSIBuff,"%d",Front1_GadSInfo.LongInt);
  576.     Front2_GadSInfo.LongInt = (long) front_gear[1];
  577.     sprintf(Front2_GadSIBuff,"%d",Front2_GadSInfo.LongInt);
  578.     Front3_GadSInfo.LongInt = (long) front_gear[2];
  579.     sprintf(Front3_GadSIBuff,"%d",Front3_GadSInfo.LongInt);
  580.  
  581.     Rear1_GadSInfo.LongInt = (long) rear_gear[0];
  582.     sprintf(Rear1_GadSIBuff,"%d",Rear1_GadSInfo.LongInt);
  583.     Rear2_GadSInfo.LongInt = (long) rear_gear[1];
  584.     sprintf(Rear2_GadSIBuff,"%d",Rear2_GadSInfo.LongInt);
  585.     Rear3_GadSInfo.LongInt = (long) rear_gear[2];
  586.     sprintf(Rear3_GadSIBuff,"%d",Rear3_GadSInfo.LongInt);
  587.     Rear4_GadSInfo.LongInt = (long) rear_gear[3];
  588.     sprintf(Rear4_GadSIBuff,"%d",Rear4_GadSInfo.LongInt);
  589.     Rear5_GadSInfo.LongInt = (long) rear_gear[4];
  590.     sprintf(Rear5_GadSIBuff,"%d",Rear5_GadSInfo.LongInt);
  591.     Rear6_GadSInfo.LongInt = (long) rear_gear[5];
  592.     sprintf(Rear6_GadSIBuff,"%d",Rear6_GadSInfo.LongInt);
  593.     Rear7_GadSInfo.LongInt = (long) rear_gear[6];
  594.     sprintf(Rear7_GadSIBuff,"%d",Rear7_GadSInfo.LongInt);
  595.  
  596.     /* read in colors */
  597.     for (i=0;i<PaletteColorCount;i++) color[i] = -1;
  598.     for (i=0;i<PaletteColorCount;i++)
  599.         if (1 != fscanf(fp,",%d",&color[i])) goto skip;
  600.     for (i=0;i<PaletteColorCount;i++) if (color[i] == -1) goto skip;
  601.     for (i=0;i<PaletteColorCount;i++)  Palette[i] = (USHORT) color[i];
  602.     LoadRGB4(&vP,&Palette,PaletteColorCount);
  603.   skip:
  604.  
  605.     if (!check_gears())  return;   /* bad data check   */
  606.  
  607.     set_gads();
  608.     set_menus();
  609.  
  610.     calc_it();         /* Calc the ratios */
  611.  
  612.     redraw_scr();      /* Update screen   */
  613.  
  614.     display_it();      /* Display the ratios */
  615. }
  616.  
  617. /*
  618.  *    Save the current data in an ASCII file
  619.  */
  620.  
  621. do_save()
  622. {
  623.     FILE *fp;
  624.     int i;
  625.  
  626.     if (!check_gears()) return;
  627.  
  628.     select_file(1);
  629.     if (filename[0] == '\0') return;
  630.  
  631.     while ((fp = fopen(filename,"w")) == NULL)
  632.         {
  633.         infailtxt2.IText = (UBYTE *) filename;
  634.         if (AutoRequest(wG,&infailtxt,&retrytxt,&cantxt,
  635.             0L,0L,reqlen(filename),75L)) continue;
  636.         return;
  637.         }
  638.     AddFileIOName(FIOSupp,filename); /* tell FIO about new file */
  639.  
  640.     fprintf(fp,"%d,%d,%d,",front,rear,Diameter_GadSInfo.LongInt);
  641.     if (inmm_Gad.Flags & SELECTED ) fprintf(fp,"m");
  642.     else fprintf(fp,"i");
  643.     /* do gears */
  644.     for (i=0;i<front;i++) fprintf(fp,",%2.0f",front_gear[i]);
  645.     for (i=0;i<rear;i++) fprintf(fp,",%2.0f",rear_gear[i]);
  646.     /* do colors */
  647.     cm = Sc->ViewPort.ColorMap;
  648.     if (cm) for (i = 0; i < 8; i++) fprintf(fp,",%d",GetRGB4(cm, (long) i));
  649.     fprintf(fp,"\n");
  650.     fclose(fp);
  651.  
  652. }
  653.  
  654.  
  655. /*
  656.  * Redraw Window
  657.  */
  658.  
  659. redraw_scr()
  660. {
  661.     RemoveGList(wG,&GadgetList1,-1L); /* remove all gadgets */
  662.     SetAPen(rpG,0L); /* clear the window */
  663.     RectFill(rpG,2L,11L,(long)(wG->Width-3),(long)(wG->Height-2));
  664.     AddGList(wG,&GadgetList1,0L,-1L,NULL);  /* put back gadgets */
  665.     RefreshGList(&GadgetList1,wG,NULL,-1L); /* redraw the gadgets */
  666.     PrintIText(rpG,&IntuiTextList1,0L,0L); /* write window text */
  667.     SetAPen(rpG,7L);  /* set draw color */
  668. }
  669.  
  670.  
  671. /*
  672.  * Select a file
  673.  */
  674.  
  675. select_file(io)
  676. int io;
  677. {
  678.     struct Window *OpenWindow(), *wF = NULL;
  679.     struct FileLock *lock = NULL;
  680.  
  681.     ClearMenuStrip(wG);
  682.  
  683.     if (NULL == FIOSupp)
  684.         if (NULL == (FIOSupp = GetFileIOSupport()))
  685.             {
  686.             AutoRequest(wG,&fiofailtxt,0L,&cantxt,0L,0L,300L,75L) ;
  687.             SetMenuStrip(wG,&MenuList1);    /* re-attach my Menu */
  688.             return;
  689.             }
  690.  
  691.     /* set up title for file requester */
  692.     if (io == 0) FIOSupp->ReqTitle = (UBYTE *) load_title;
  693.     else FIOSupp->ReqTitle = (UBYTE *) save_title;
  694.  
  695.     wF = OpenWindow(&NewWindowStructure3);    /* open the window */
  696.     if ( wF == NULL )
  697.         {
  698.         AutoRequest(wG,&winfailtxt,0L,&oktxt,0L,0L,300L,75L);
  699.         SetMenuStrip(wG,&MenuList1);    /* re-attach my Menu */
  700.         return;
  701.         }
  702.  
  703.     filename[0] = '\0';
  704.     if (GetFileIOName(FIOSupp,wF))
  705.         BuildFileIOPathname(FIOSupp,filename);
  706.  
  707.     if (wF) CloseWindow(wF);
  708.     if (lock) UnLock(lock);
  709.     SetMenuStrip(wG,&MenuList1);    /* attach my Menu */
  710. }
  711.  
  712.  
  713. /*
  714.  *  Calculate size of requester needed for given filename
  715.  */
  716.  
  717. reqlen(filename)
  718. char *filename;
  719. {
  720.     int r;
  721.     r = TextLength(rpG,filename,strlen(filename))+50;
  722.     if (r < 300) r = 300;
  723.     if (r > 640) r = 640;
  724.     return (r) ;
  725. }
  726.  
  727. /*
  728.  *
  729.  *   Quick Sort routine. From Matt Dillon/Steve Drews Shell
  730.  *
  731.  */
  732.  
  733. QuickSort(av, n)
  734. int av[];
  735. int n;
  736. {
  737.    int b;
  738.  
  739.    if (n > 0) {
  740.       b = QSplit(av, n);
  741.       QuickSort(av, b);
  742.       QuickSort(av+b+1, n - b - 1);
  743.    }
  744. }
  745.  
  746.  
  747. /*
  748.  * QSplit called as a second routine so I don't waste stack on QuickSort's
  749.  * recursivness.
  750.  */
  751.  
  752. QSplit(av, n)
  753. int av[];
  754. int n;
  755. {
  756.    int i, b;
  757.    int element, scr;
  758.  
  759.    element = av[0];
  760.    for (b = 0, i = 1; i < n; ++i) {
  761.       if (ratios[av[i]] < ratios[element]) {
  762.          ++b;
  763.          scr = av[i]; av[i] = av[b]; av[b] = scr;
  764.       }
  765.    }
  766.    scr = av[0]; av[0] = av[b]; av[b] = scr;
  767.    return (b);
  768. }
  769.  
  770. #ifdef AZTEC_C
  771. _abort()
  772. {
  773.     done(13);
  774. }
  775. #endif
  776.