home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Frozen Fish 2: PC
/
frozenfish_august_1995.bin
/
bbs
/
d03xx
/
d0304.lha
/
Gears
/
gears.c
< prev
next >
Wrap
C/C++ Source or Header
|
1990-01-10
|
17KB
|
776 lines
/*
* GEARS : Bicycle gear ratio Calculator
*
* Version 1
*
* by Joel Swank 9-19-89
*
*/
/********* INCLUDES ************************ */
#include <exec/types.h>
#include <exec/io.h>
#include <exec/memory.h>
#include <libraries/dos.h>
#include <intuition/intuition.h>
#include <stdio.h>
#include "fio.h"
/* Data in helpwin.h */
extern struct IntuiText prfailtxt ;
extern struct IntuiText badfiletxt ;
extern struct IntuiText fiofailtxt ;
extern struct IntuiText winfailtxt ;
extern struct IntuiText lockfailtxt ;
extern struct IntuiText geartxt ;
extern struct IntuiText infailtxt ;
extern struct IntuiText infailtxt2 ;
extern struct IntuiText oktxt ;
extern struct IntuiText cantxt ;
extern struct IntuiText retrytxt ;
extern struct NewWindow NewWindowStructureHelp;
extern struct NewWindow NewWindowStructure3;
extern char gear_buff[];
/* Data in doargs.c */
extern char filename[];
/* Defines for setting/clearing GADGDISABLED flag */
#define OffGad(gad) (gad).Flags = gad.Flags | GADGDISABLED
#define OnGad(gad) (gad).Flags = gad.Flags & ~(GADGDISABLED)
#define OffMenu(item) (item).Flags = item.Flags & ~(CHECKED)
#define OnMenu(item) (item).Flags = item.Flags | CHECKED
extern struct IntuitionBase *IntuitionBase ;
extern struct GfxBase *GfxBase ;
extern struct DosLibrary *DosBase ;
struct Screen *OpenScreen();
struct Screen *Sc = NULL;
struct ViewPort vP;
struct Window *wG = NULL;
struct Window *wF = NULL;
struct RastPort *rpG;
struct IntuiMessage *message; /* the message from the IDCMP */
struct Window *OpenWindow();
void *OpenLibrary();
struct IntuiMessage *GetMsg();
struct MenuItem *ItemAddress();
struct FileIOSupport *FIOSupp = NULL; /* fileio support stuff */
struct FileIOSupport *GetFileIOSupport();
struct FileLock *Lock();
char save_title[] = "Select File to SAVE";
char load_title[] = "Select File to LOAD";
/* get the PowerWindows 2.0 code */
#include "gearscreen.h"
/* internal data areas */
int front = 2; /* number of front gears */
int rear = 6; /* number of rear gears */
float ratios[21]; /* storage for ratios */
float front_gear[3];/* storage for front gears */
float rear_gear[7]; /* storage for rear gears */
int av[21]; /* indices for sort */
char cbuf[21][8]; /* storage for gear combos */
int count = 0; /* count of ratios */
int diameter = 27; /* wheel diameter from args */
long color[8]; /* savearea for colors */
struct ColorMap *cm; /* pointer to screen colors */
char rearmsg[] = "Bad Rear Gear: ";
char frontmsg[] = "Bad Front Gear: ";
main(argc,argv)
int argc;
char *argv[];
{
UWORD code;
ULONG class;
APTR object;
FILE *fp;
/* Open the libraries */
IntuitionBase = (struct IntuitionBase *)
OpenLibrary("intuition.library", 0L);
if (IntuitionBase == NULL)
{
done(11);
}
GfxBase = (struct GfxBase *)OpenLibrary("graphics.library", 0L);
if (GfxBase == NULL)
{
done(10);
}
DosBase = (struct DosLibrary *)OpenLibrary("dos.library", 0);
if (DosBase == NULL)
{
done(16);
}
/* Get the arguments */
filename[0] = '\0';
if (argc == 0) getWBargs();
else getCLIargs(argc,argv);
Diameter_GadSInfo.LongInt = diameter;
sprintf(Diameter_GadSIBuff,"%d",diameter);
/* Open my screen */
Sc = OpenScreen(&NewScreenStructure);
if ( Sc == NULL )
{
done(15);
}
vP = Sc->ViewPort;
LoadRGB4(&vP,&Palette,PaletteColorCount);
/* tie windows to my screen */
NewWindowStructureHelp.Screen = Sc;
NewWindowStructure3.Screen = Sc;
NewWindowStructure1.Screen = Sc;
wG = OpenWindow(&NewWindowStructure1); /* open main window */
if ( wG == NULL )
{
done(12);
}
rpG = wG->RPort; /* get a rastport pointer for the window */
PrintIText(rpG,&IntuiTextList1,0L,0L); /* write window text */
SetMenuStrip(wG,&MenuList1); /* attach my Menu */
if (filename[0] != '\0')
{
while ((fp = fopen(filename,"r")) == NULL)
{
infailtxt2.IText = (UBYTE *) filename;
if (AutoRequest(wG,&infailtxt,&retrytxt,&cantxt,
0L,0L,reqlen(filename),75L)) continue;
}
if (fp != NULL) {
read_file(fp);
fclose(fp);
}
}
/* Wait for some User interaction */
while(1)
{
WaitPort(wG->UserPort);
while( (message = (struct IntuiMessage *)
GetMsg(wG->UserPort) ) != NULL)
{
code = message->Code; /* MENUNUM */
object = message->IAddress; /* Gadget */
class = message->Class; /* IDCMP Flags */
ReplyMsg(message); /* Free the sender */
switch (class)
{
case CLOSEWINDOW :
done(0); /* close gadget clicked */
case GADGETUP:
if (object == (APTR) &Calc_Gad)
{
calc_it();
display_it();
break;
}
/* add more gadget checks here */
break;
case MENUPICK: /* menu selection made */
/* I get a NULL message whenever the user brings
up the menu but doesn't select anything */
if (code != MENUNULL) do_pick((USHORT)code);
break;
}
}
}
}
/*
* Cleanup and exit
*/
done(how)
int how;
{
if (FIOSupp) ReleaseFileIO(FIOSupp);
if (wG) ClearMenuStrip(wG);
if (wG) CloseWindow(wG);
if (Sc) CloseScreen(Sc);
if (DosBase) CloseLibrary(DosBase);
if (GfxBase != NULL) CloseLibrary(GfxBase);
if (IntuitionBase != NULL) CloseLibrary(IntuitionBase);
exit(how);
/* exit codes
* 0 User requested
* 10 graphics lib open fail
* 11 intuition lib open fail
* 12 main window open fail
* 13 _abort() called
* 14 Bad CLI args
* 15 Custom Screen open Fail
* 16 Dos lib open fail
*/
}
/*
* do_pick : handle chain of menu selections
*/
do_pick(menunum)
USHORT menunum;
{
struct MenuItem *item, *ItemAddress();
while (menunum != MENUNULL)
{
switch(MENUNUM(menunum))
{
case 0: /* Project Menu */
switch(ITEMNUM(menunum))
{
case 0: /* Load */
do_load();
break;
case 1: /* Save */
do_save();
break;
case 2: /* Print */
do_print();
break;
case 3: /* Colors */
ClearMenuStrip(wG);
DoColorWindow(Sc,170,15,0,TRUE);
SetMenuStrip(wG,&MenuList1); /* re-attach my Menu */
break;
case 4: /* Help */
help();
break;
case 5: /* About */
about();
break;
case 6: /* Quit */
done(0);
}
break;
case 1: /* Gears Menu */
switch(ITEMNUM(menunum))
{
case 0: /* Front Gear selection */
/* Three mutually excluded items. intuition keeps track,
I have to enable/disable integer input gadgets and
redraw the window */
switch(SUBNUM(menunum))
{
case 0: /* 1 */
front = 1;
break;
case 1: /* 2 */
front = 2;
break;
case 2: /* 3 */
front = 3;
break;
}
break;
case 1: /* Rear Gear selection */
/* Five mutually excluded items. intuition keeps track,
I have to enable/disable integer input gadgets and
redraw the window */
switch(SUBNUM(menunum))
{
case 0: /* 3 */
rear = 3;
break;
case 1: /* 4 */
rear = 4;
break;
case 2: /* 5 */
rear = 5;
break;
case 3: /* 6 */
rear = 6;
break;
case 4: /* 7 */
rear = 7;
break;
}
break;
}
set_gads();
redraw_scr();
break;
default: /* What's this garbage ? */
menunum = MENUNULL;
} /* end switch MENUNUM */
/* Get chain to next selection. NextSelect contains another item
when the user makes multiple menu selections */
item = ItemAddress(&MenuList1,(long) menunum);
menunum = item->NextSelect;
}
}
/*
* Calculate and display gear table
*/
calc_it()
{
int i,j;
if (!check_gears()) return; /* validate the gears */
count = 0; /* Calculate the ratios */
for (i=0; i<front; i++)
{
for (j=0; j<rear; j++)
{
ratios[count] = front_gear[i]/rear_gear[j]
* Diameter_GadSInfo.LongInt;
sprintf(cbuf[count],"%2.0fx%2.0f", front_gear[i], rear_gear[j]);
count++;
}
}
for (i=0; i<21; i++) av[i] = i; /* init index array */
QuickSort(av, count); /* sort the indices */
}
/*
* check_gears : validate reasonable values for all active gears
*/
check_gears()
{
int i;
/* capture all gear values from string gadgets */
front_gear[0] = Front1_GadSInfo.LongInt;
front_gear[1] = Front2_GadSInfo.LongInt;
front_gear[2] = Front3_GadSInfo.LongInt;
rear_gear[0] = Rear1_GadSInfo.LongInt;
rear_gear[1] = Rear2_GadSInfo.LongInt;
rear_gear[2] = Rear3_GadSInfo.LongInt;
rear_gear[3] = Rear4_GadSInfo.LongInt;
rear_gear[4] = Rear5_GadSInfo.LongInt;
rear_gear[5] = Rear6_GadSInfo.LongInt;
rear_gear[6] = Rear7_GadSInfo.LongInt;
for (i=0;i<rear;i++)
if (rear_gear[i] < 10.0 || rear_gear[i] > 40.0)
{
sprintf(gear_buff,"%s%2.0f",rearmsg,rear_gear[i]);
AutoRequest(wG,&geartxt,0L,&oktxt,0L,0L,300L,75L);
return(FALSE);
}
for (i=0;i<front;i++)
if (front_gear[i] < 10.0 || front_gear[i] > 80.0)
{
sprintf(gear_buff,"%s%2.0f",frontmsg,front_gear[i]);
AutoRequest(wG,&geartxt,0L,&oktxt,0L,0L,300L,75L);
return(FALSE);
}
return(TRUE);
}
/*
* Set Disabled bit on all gear string gadgets
*/
set_gads()
{
if (front > 1) OnGad(Front2_Gad);
else OffGad(Front2_Gad);
if (front > 2) OnGad(Front3_Gad);
else OffGad(Front3_Gad);
if (rear > 3) OnGad(Rear4_Gad);
else OffGad(Rear4_Gad);
if (rear > 4) OnGad(Rear5_Gad);
else OffGad(Rear5_Gad);
if (rear > 5) OnGad(Rear6_Gad);
else OffGad(Rear6_Gad);
if (rear > 6) OnGad(Rear7_Gad);
else OffGad(Rear7_Gad);
}
/*
* Set the menus according to front and rear
*/
set_menus()
{
if (rear == 3) OnMenu(SubItem1);
else OffMenu(SubItem1);
if (rear == 4) OnMenu(SubItem2);
else OffMenu(SubItem2);
if (rear == 5) OnMenu(SubItem3);
else OffMenu(SubItem3);
if (rear == 6) OnMenu(SubItem4);
else OffMenu(SubItem4);
if (rear == 7) OnMenu(SubItem5);
else OffMenu(SubItem5);
if (front == 1) OnMenu(SubItem6);
else OffMenu(SubItem6);
if (front == 2) OnMenu(SubItem7);
else OffMenu(SubItem7);
if (front == 3) OnMenu(SubItem8);
else OffMenu(SubItem8);
}
/*
* Display ratios in main window
* (Assumes calc_it has been done)
*/
#define XPOS 170
#define LINESIZE 9
char header[] = "Gear Wheel Size Spacing";
char disp_buff[100], temp_buff[30];
display_it()
{
int ypos = 20, i, j;
SetAPen(rpG,7L); /* set draw color */
Move(rpG,XPOS,ypos);
Text(rpG,header,sizeof(header)-1);
ypos += LINESIZE;
for (i=0; i<count; i++, ypos += LINESIZE)
{
bld_buf(i);
Move(rpG,XPOS,ypos);
Text(rpG,disp_buff,strlen(disp_buff));
}
}
/*
* Print the table
*/
do_print()
{
int i;
FILE *fp;
while ((fp = fopen("PRT:","w")) == NULL)
{
if (AutoRequest(wG,&prfailtxt,&retrytxt,&cantxt,
0L,0L,300L,75L)) continue;
return;
}
fprintf(fp,"%s\n",header);
for (i=0; i<count; i++)
{
bld_buf(i);
fprintf(fp,"%s\n",disp_buff);
}
fclose(fp);
}
/*
* Build a line of print
*/
bld_buf(i)
int i;
{
int j;
j = av[i];
sprintf(disp_buff,"%s %7.2f",cbuf[j],ratios[j]);
if (i>0) {
sprintf(temp_buff," %6.2f",ratios[j] - ratios[av[i-1]]);
strcat(disp_buff,temp_buff);
}
if (i>1) {
sprintf(temp_buff," %6.2f",ratios[j] - ratios[av[i-2]]);
strcat(disp_buff,temp_buff);
}
if (i>2) {
sprintf(temp_buff," %6.2f",ratios[j] - ratios[av[i-3]]);
strcat(disp_buff,temp_buff);
}
}
/*
* Load data from an ASCII file
*/
do_load()
{
FILE *fp;
select_file(0);
if (filename[0] == '\0') return;
while ((fp = fopen(filename,"r")) == NULL)
{
infailtxt2.IText = (UBYTE *) filename;
if (AutoRequest(wG,&infailtxt,&retrytxt,&cantxt,
0L,0L,reqlen(filename),75L)) continue;
return;
}
read_file(fp);
fclose(fp);
}
/*
* Read in data from open file
*/
read_file(fp)
FILE *fp;
{
int i;
char x;
int fr = front;
int re = rear;
i = fscanf(fp,"%d, %d",&front,&rear);
if (i != 2 || rear < 3 || rear >7 || front < 1 || front >3)
{
infailtxt2.IText = (UBYTE *) filename;
AutoRequest(wG,&badfiletxt,0L,&oktxt,0L,0L,reqlen(filename),75L);
front = fr;
rear = re;
return(FALSE);
}
fscanf(fp,", %d ,",&Diameter_GadSInfo.LongInt);
sprintf(Diameter_GadSIBuff,"%d",Diameter_GadSInfo.LongInt);
fscanf(fp,"%c",&x);
if (x == 'm') inmm_Gad.Flags |= SELECTED;
if (x == 'i') inmm_Gad.Flags &= ~SELECTED;
for (i=0;i<front;i++) fscanf(fp,",%2f",&front_gear[i]);
for (i=0;i<rear;i++) fscanf(fp,",%2f",&rear_gear[i]);
/* Put the data in the string gadgets */
Front1_GadSInfo.LongInt = (long) front_gear[0];
sprintf(Front1_GadSIBuff,"%d",Front1_GadSInfo.LongInt);
Front2_GadSInfo.LongInt = (long) front_gear[1];
sprintf(Front2_GadSIBuff,"%d",Front2_GadSInfo.LongInt);
Front3_GadSInfo.LongInt = (long) front_gear[2];
sprintf(Front3_GadSIBuff,"%d",Front3_GadSInfo.LongInt);
Rear1_GadSInfo.LongInt = (long) rear_gear[0];
sprintf(Rear1_GadSIBuff,"%d",Rear1_GadSInfo.LongInt);
Rear2_GadSInfo.LongInt = (long) rear_gear[1];
sprintf(Rear2_GadSIBuff,"%d",Rear2_GadSInfo.LongInt);
Rear3_GadSInfo.LongInt = (long) rear_gear[2];
sprintf(Rear3_GadSIBuff,"%d",Rear3_GadSInfo.LongInt);
Rear4_GadSInfo.LongInt = (long) rear_gear[3];
sprintf(Rear4_GadSIBuff,"%d",Rear4_GadSInfo.LongInt);
Rear5_GadSInfo.LongInt = (long) rear_gear[4];
sprintf(Rear5_GadSIBuff,"%d",Rear5_GadSInfo.LongInt);
Rear6_GadSInfo.LongInt = (long) rear_gear[5];
sprintf(Rear6_GadSIBuff,"%d",Rear6_GadSInfo.LongInt);
Rear7_GadSInfo.LongInt = (long) rear_gear[6];
sprintf(Rear7_GadSIBuff,"%d",Rear7_GadSInfo.LongInt);
/* read in colors */
for (i=0;i<PaletteColorCount;i++) color[i] = -1;
for (i=0;i<PaletteColorCount;i++)
if (1 != fscanf(fp,",%d",&color[i])) goto skip;
for (i=0;i<PaletteColorCount;i++) if (color[i] == -1) goto skip;
for (i=0;i<PaletteColorCount;i++) Palette[i] = (USHORT) color[i];
LoadRGB4(&vP,&Palette,PaletteColorCount);
skip:
if (!check_gears()) return; /* bad data check */
set_gads();
set_menus();
calc_it(); /* Calc the ratios */
redraw_scr(); /* Update screen */
display_it(); /* Display the ratios */
}
/*
* Save the current data in an ASCII file
*/
do_save()
{
FILE *fp;
int i;
if (!check_gears()) return;
select_file(1);
if (filename[0] == '\0') return;
while ((fp = fopen(filename,"w")) == NULL)
{
infailtxt2.IText = (UBYTE *) filename;
if (AutoRequest(wG,&infailtxt,&retrytxt,&cantxt,
0L,0L,reqlen(filename),75L)) continue;
return;
}
AddFileIOName(FIOSupp,filename); /* tell FIO about new file */
fprintf(fp,"%d,%d,%d,",front,rear,Diameter_GadSInfo.LongInt);
if (inmm_Gad.Flags & SELECTED ) fprintf(fp,"m");
else fprintf(fp,"i");
/* do gears */
for (i=0;i<front;i++) fprintf(fp,",%2.0f",front_gear[i]);
for (i=0;i<rear;i++) fprintf(fp,",%2.0f",rear_gear[i]);
/* do colors */
cm = Sc->ViewPort.ColorMap;
if (cm) for (i = 0; i < 8; i++) fprintf(fp,",%d",GetRGB4(cm, (long) i));
fprintf(fp,"\n");
fclose(fp);
}
/*
* Redraw Window
*/
redraw_scr()
{
RemoveGList(wG,&GadgetList1,-1L); /* remove all gadgets */
SetAPen(rpG,0L); /* clear the window */
RectFill(rpG,2L,11L,(long)(wG->Width-3),(long)(wG->Height-2));
AddGList(wG,&GadgetList1,0L,-1L,NULL); /* put back gadgets */
RefreshGList(&GadgetList1,wG,NULL,-1L); /* redraw the gadgets */
PrintIText(rpG,&IntuiTextList1,0L,0L); /* write window text */
SetAPen(rpG,7L); /* set draw color */
}
/*
* Select a file
*/
select_file(io)
int io;
{
struct Window *OpenWindow(), *wF = NULL;
struct FileLock *lock = NULL;
ClearMenuStrip(wG);
if (NULL == FIOSupp)
if (NULL == (FIOSupp = GetFileIOSupport()))
{
AutoRequest(wG,&fiofailtxt,0L,&cantxt,0L,0L,300L,75L) ;
SetMenuStrip(wG,&MenuList1); /* re-attach my Menu */
return;
}
/* set up title for file requester */
if (io == 0) FIOSupp->ReqTitle = (UBYTE *) load_title;
else FIOSupp->ReqTitle = (UBYTE *) save_title;
wF = OpenWindow(&NewWindowStructure3); /* open the window */
if ( wF == NULL )
{
AutoRequest(wG,&winfailtxt,0L,&oktxt,0L,0L,300L,75L);
SetMenuStrip(wG,&MenuList1); /* re-attach my Menu */
return;
}
filename[0] = '\0';
if (GetFileIOName(FIOSupp,wF))
BuildFileIOPathname(FIOSupp,filename);
if (wF) CloseWindow(wF);
if (lock) UnLock(lock);
SetMenuStrip(wG,&MenuList1); /* attach my Menu */
}
/*
* Calculate size of requester needed for given filename
*/
reqlen(filename)
char *filename;
{
int r;
r = TextLength(rpG,filename,strlen(filename))+50;
if (r < 300) r = 300;
if (r > 640) r = 640;
return (r) ;
}
/*
*
* Quick Sort routine. From Matt Dillon/Steve Drews Shell
*
*/
QuickSort(av, n)
int av[];
int n;
{
int b;
if (n > 0) {
b = QSplit(av, n);
QuickSort(av, b);
QuickSort(av+b+1, n - b - 1);
}
}
/*
* QSplit called as a second routine so I don't waste stack on QuickSort's
* recursivness.
*/
QSplit(av, n)
int av[];
int n;
{
int i, b;
int element, scr;
element = av[0];
for (b = 0, i = 1; i < n; ++i) {
if (ratios[av[i]] < ratios[element]) {
++b;
scr = av[i]; av[i] = av[b]; av[b] = scr;
}
}
scr = av[0]; av[0] = av[b]; av[b] = scr;
return (b);
}
#ifdef AZTEC_C
_abort()
{
done(13);
}
#endif