/*********************************************************************/ /* */ /* PORSCHE PERFORMANCE SUMMARY PROGRAM */ /* */ /* Program to calculate mph in each gear, given the tire size */ /* and gearbox ratios. Uses screens generated by PANEL(tm), */ /* windowing functions from WINDOWS FOR C(tm), and miscellaneous */ /* functions from C-FOOD SMORGESBORD(tm). */ /* */ /* Needed to run: PPERFORM.EXE (this program) */ /* PERF1.PNL (PANEL description for screen 1) */ /* PERF3.PNL (PANEL description for screen 3) */ /* PERF4.PNL (PANEL description for screen 4) */ /* PERF5.PNL (PANEL description for screen 5) */ /* COPY84.PNL (PANEL description for copyright) */ /* PANEL.VDU (terminal description for PANEL) */ /* GHELP.HLP (online help file) */ /* */ /* To use the PPERFORM.DAT file to store torque values: */ /* */ /* BTRIEVE.EXE (BTRIEVE Record Manager) */ /* PPERFORM.DAT (Saved values file) */ /* */ /*********************************************************************/ #define WN_HISTORY /* include old functions */ #include /* for WINDOW */ #include /* for WINDOW */ #include /* select panel interface */ #include /* select panel interface */ #include /* include screen definition */ #include /* include screen definition */ #include /* include screen definition */ #include /* include screen definition */ #include /* screen-level interface */ #include /* btrieve function codes */ /*********************************************************************/ /* */ /* The following defines take care of the starting line of each */ /* section of the help file, to provide a context-sensitive screen. */ /* */ /*********************************************************************/ #define HTITLE 0 /* help for title field */ #define HFILE 44 /* help for file entry */ #define HWIDTH 91 /* help for width field */ #define HSECT 101 /* help for section field */ #define HDIA 111 /* help for diameter field */ #define HMODEL 118 /* help for model field */ #define HGEAR 128 /* help for gear fields */ #define HTORQ 152 /* help for torque entries */ #define HAERO 166 /* help for aerodynamics */ /*********************************************************************/ /* */ /* The structure stndardg is initialized with the standard gear */ /* values that may be selected off the first screen. */ /* */ /*********************************************************************/ struct stgear { int stang[12]; /* int array of gear num/den */ } stndardg[14] = { /* space for 14 gear sets */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,0, 0 }, /* space for other vals */ { 11,35,18,33,23,29,27,25,29,21,7,31 }, /* 1974 911 5-speed */ { 11,35,18,33,23,29,26,26,28,23,8,31 }, /* 1975-79 911 5-speed */ { 11,35,18,32,23,29,26,26,28,23,8,31 }, /* 1980-81 911 5-speed */ { 16,36,23,30,28,25,32,21, 0, 0,9,38 }, /* 1976 911 Turbo (std) */ { 16,36,23,30,28,25,32,21, 0, 0,9,36 }, /* 1976 911 Turbo (50%) */ { 16,36,23,30,28,25,32,21, 0, 0,9,38 }, /* 1977 911 Turbo */ { 16,36,23,30,28,25,32,20, 0, 0,9,38 }, /* 1978-81 911 Turbo */ { 11,34,18,34,23,29,27,25,31,22,7,31 }, /* 1970-74 914 5-speed */ { 11,34,18,32,23,28,27,25,29,22,7,31 }, /* 1970-72 914-6 */ { 10,36,16,34,25,34,30,29, 0, 0,9,35 }, /* 1977 924 4-speed */ { 10,36,16,34,24,35,28,31,37,27,9,35 }, /* 1980-82 924 Turbo */ { 10,36,16,34,24,35,30,28,37,27,9,35 }, /* 1983-84 944 5-speed */ { 17,44,22,39,26,34,29,28,32,23,12,33 } /* 1978-82 928 manual */ }; /*********************************************************************/ /* */ /* Once the gear values have been selected, the resulting ratios */ /* are stored in the array of doubles gratio. The mph at each */ /* rpm is stored in the array gmph for each gear. Torque values */ /* for each rpm from 2000-7800, input from screen PERF3, are */ /* stored in array torq. Finally, array shift is used to store */ /* the shift points calculated by the program. */ /* */ /*********************************************************************/ double gratio[6]; /* array of gear ratios */ struct gearmph { double gmph[36]; /* dbl array of mph at rpm */ } mphrpm[5]; /* space for 5 gears */ float torq[30]; /* array of torque values */ float hp[30]; /* array of horsepower vals */ float hpr[30]; /* array of hp req'd values */ int shift[4]; /* array of shift points */ /*********************************************************************/ /* */ /* The following definitions are used for the WINDOWS FOR C */ /* functions. This allows a help text file to be displayed on the */ /* screen while saving the current contents of the screen, and */ /* also allows the user to page through the help file. */ /* */ /*********************************************************************/ MFILE fr; /* memory file structure */ MFILEPTR frp; /* pointer to file structure */ WINDOW wn1; /* help file window */ WINDOW wn2; char *lineptr2[25]; /* pointer to array of ptrs */ int vmode; /* video mode */ /*********************************************************************/ /* */ /* The following definitions are used by BTRIEVE to manage the file */ /* in which the performance values may be stored. */ /* */ /*********************************************************************/ struct data_rec { /* torque records */ char rkey[24]; /* record key (yr/mod/id */ int rmodeln; /* model number */ int rgears[12]; /* gears */ int rtorqsw; /* if valid torque values */ float rtorqs[30]; /* array of torque values */ float rcd; /* coefficient of drag */ float rarea; /* cross-sectional area */ char reserved[15]; /* reserved space */ }; struct data_rec data_buf, *rec; char key1_buf[12]; char pos_blk[128]; /*********************************************************************/ /* */ /* The main program starts here. */ /* */ /*********************************************************************/ main() { int value,rpm,i,j,k; /* misc integers */ int numer,denom,numer5,denom5; /* gear ratios (numer/demon) */ double twidth,tsect,tdia,ewidth; /* tire/wheel data */ double fdratio,rpmile,ar,grat; /* float computations */ double atof(),pow(); /* functions return doubles */ double mphl,incr; /* mph in lower gear */ int dwidth,dsect,ddia; /* displayed width */ int rc,maxg,mod; /* function return code */ int torqsw,prtsw,recsw,aerosw; /* switches */ int filesw,savesw,btrsw; /* more switches */ int m928sw; /* 928 switch */ int btrstop; /* BTRIEVE stop switch */ char resp[2]; /* resp to messages */ char msg[80]; /* message */ struct stgear *gptr; /* pointer to structure */ struct gearmph *mptr; /* pointer to structure */ struct gearmph *mptrl; /* pointer to structure */ struct gearmph *mptrh; /* pointer to structure */ panafcb *fldptr; /* pointer to fld ctrl blk */ char *fp; /* pointer to char field */ int status,error; /* integers */ float maxtorq,v,cd,area; /* floats */ char *p; /* pointer to characters */ char *malloc(); /* returns ptr to chars */ unsigned block; /* amount of memory to alloc */ char ctitle[71]; /* title line */ int vmode,oldmode; /* video modes */ /*********************************************************************/ /* */ /* Functions in all caps, beginning with "PA", are PANEL functions */ /* to use pre-generated screens for input and output. */ /* */ /* The PAINIT function reads in the PANEL.VDU file, which contains */ /* the terminal characteristics for this monitor. This would allow */ /* this program to be run on any monitor by simply changing the */ /* definitions in the PANEL.VDU file. */ /* */ /* The current video mode is checked and, if not 80 columns, and 80 */ /* column mode is set. The mode will be restored at program end. */ /* */ /*********************************************************************/ if (PAINIT("")) { /* if can't read PANEL.VDU */ printf("\nCannot open PANEL.VDU file"); exit(); /* quit */ } init_wfc(); /* initialize Windows for C */ vmode = pcvgvm(); /* get video mode */ switch (vmode) { case 10240: /* CGA text, 40 col mono */ pcvsvm(2); /* set to 80 col mono */ oldmode = 0; /* save old mode number */ case 10241: /* CGA text, 40 col color */ pcvsvm(3); /* set to 80 col color */ oldmode = 1; /* save old mode number */ case 10244: /* CGA graphics, 40 col color*/ pcvsvm(6); /* set to 80 col mono */ oldmode = 4; /* save old mode number */ case 10245: /* CGA graphics, 40 col mono */ pcvsvm(6); /* set to 80 col mono */ oldmode = 5; /* save old mode number */ default: /* already in 80 col mode */ oldmode = vmode - 2048; /* get mode number */ } PAFUNC(1); /* send init sequence */ /*********************************************************************/ /* */ /* After clearing the screen, the help file is read into memory */ /* and an array of pointers to the lines of text is built. */ /* */ /*********************************************************************/ if ((frp = mf_def("ghelp.hlp",200,80)) == NULLP) /* init mem file */ PAMSGE("Error allocating help file"); /* display message */ if (mf_rd(frp) == 0) /* read help file into array */ PAMSGE("Error reading in help file"); /* display message */ /* WINDOW wn1 = {5,20,5,74,0,0,NORMAL,0,NO_WRAP,0,1,1,1,&bdr_dot,0,&fr}; */ def_wn(&wn1,5,20,5,74,0,0,&bdr_dot); /* define help window */ wn1.wrap = NO_WRAP; /* do not wrap lines */ wn1.popup = YES; /* pop up window */ wn1.frp = frp; /* pointer to file structure */ /* WINDOW wn2 = {8,18,10,69,0,0,NORMAL,0,NO_WRAP,0,1,1,1,&bdr_0,0,0}; */ def_wn(&wn2,8,18,10,69,0,0,&bdr_0); /* define help window */ wn2.wrap = NO_WRAP; /* do not wrap lines */ /*********************************************************************/ /* */ /* The d_cpy84 function displays the copyright screen and waits */ /* for the user to press any key to continue. */ /* */ /*********************************************************************/ d_cpy84(); /* display copyright screen */ PAFUNC(3); /* clear screen */ rec = &data_buf; /* init pointer to data buf */ /* error = btr_chk(); */ /* check if BTRIEVE loaded */ error = 0; /* test */ strtbtr: if (error) { /* Record Manager inactive */ btrstop = 1; /* stop BTRIEVE when done */ block = 8000; /* need 8000 bytes */ p = malloc(block); /* alloc memory for windows */ if (p == NULL) { printf("\nCould not allocate memory block - PRESS ANY KEY"); ki(); } error = forklp("btrieve","btrieve","/M:32","/P:1024",NULL); if (error) { printf("\nCould not start BTRIEVE Record Manager - PRESS ANY KEY"); ki(); btrsw = 0; /* BTRIEVE not available */ } else { wait(); btrsw = 1; /* BTRIEVE available */ } if (p) { /* memory block allocated */ error = free(p); /* release memory block */ if (error) { printf("\nCould not release memory block - PRESS ANY KEY"); ki(); } } } else { btrsw = 1; /* turn on BTRIEVE switch */ btrstop = 0; /* do not stop BTRIEVE */ } /*********************************************************************/ /* */ /* The file of values, PPERFORM.DAT, is opened. If a status code */ /* of 24 is returned, it means that the BTRIEVE record manager */ /* was started with a page size of 512 instead of the 1024 needed */ /* by this program. In this case, the Record Manager is ended */ /* and restarted with the proper parameters. */ /* */ /*********************************************************************/ if (btrsw) { status = BTRIEVE(b_open,pos_blk,&data_buf,"pperform.dat",0); if (status == 24) { /* page size too large */ status = BTRIEVE(b_stop,pos_blk,&data_buf,key1_buf,0); if (status == 0) { btrsw = 0; /* clear btrsw */ goto strtbtr; /* restart BTRIEVE */ } } if (status != 0) { printf("\nCould not open PPERFORM.DAT - PRESS ANY KEY"); filesw = 0;; /* file cannot be used */ recsw = 0; /* record cannot be used */ savesw = 0; /* record cannot be saved */ ki(); } else { filesw = 1; } } if (! filesw) { /* no file available */ recsw = 0; /* no record available */ savesw = 0; /* do not save entries */ torqsw = 0; /* turn off torque switch */ goto start; } /*********************************************************************/ /* */ /* The video mode is retrieved. If a color monitor is in use, */ /* then the help window will have a different background color. */ /* */ /*********************************************************************/ vmode = pcvgvm(); /* get video mode */ /*********************************************************************/ /* */ /* A screen is displayed to request a record from the file. If */ /* none is found, then the user may create an entry. */ /* */ /*********************************************************************/ PAFUNC(3); /* clear screen */ PAUSEP(&pPERF4,0); /* bring panel into use */ PANELS(pdisp); /* display fixed data */ PANELS(ppadf); /* pad fields with fill char */ PANELS(pshow); /* display input fields */ screenrd: PAMSGE("F5 = Help Esc = Quit"); /* display message */ for (;;) { rc = PANELS(pread); /* read input fields */ switch (rc) { case 0: /* normal read */ case 1: /* CR only */ PANELS(pdelf); /* delete all fill chars */ if (strcmp(PYEAR," ") == 0 && strcmp(PMODEL," ") == 0) { PAFUNC(6); /* ring bell */ PAMSGE("You must enter year/model or model only - press any key"); ki(); /* wait for key pressed */ continue; /* loop back */ } if (strcmp(PMODEL," ") == 0) { PAFUNC(6); /* ring bell */ PAMSGE("You must enter model - press any key"); ki(); /* wait for key pressed */ continue; /* loop back */ } break; case 15: /* F5 */ help(HFILE); continue; /* loop back */ case 2: /* escape */ recsw = 0; /* no record available */ savesw = 0; /* do not save entries */ torqsw = 0; /* turn off torque switch */ goto start; /* continue with program */ default: PAFUNC(6); /* ring bell */ continue; } break; } for (i = 0,k = 0; i < 2; i++,k++) data_buf.rkey[k] = PYEAR[i]; for (i = 0; i < 12; i++,k++) data_buf.rkey[k] = PMODEL[i]; for (i = 0; i < 10; i++,k++) data_buf.rkey[k] = PID[i]; if (strcmp(&PYEAR," ") == 0) { /* generic search */ for (i = 0; i < 12; i++) key1_buf[i] = PMODEL[i]; bw_list(); /* list entries in window */ PANELS(pzero); /* clear fields to fill char */ PANELS(pshow); /* display input fields */ goto screenrd; /* re-read screen */ } status = BTRIEVE(b_geteq,pos_blk,&data_buf,&data_buf,0); chkstat: if (status != 0) { PAFUNC(6); /* ring bell */ PAMSGE("NO MATCH - Retry / Create / Bypass / Help (R/C/B/H)? R"); strcpy(&resp,"R"); /* init resp field */ PAANSW(resp,upper+crreq+echo); /* wait for response */ if (strcmp(&resp,"R") == 0) { /* retry requested */ PANELS(pzero); /* clear fields to fill char */ PANELS(pshow); /* display input fields */ goto screenrd; /* re-read screen */ } if (strcmp(&resp,"C") == 0) { savesw = 1; /* need to save entries */ recsw = 0; /* no record available */ torqsw = 0; /* turn off torque switch */ rec->rmodeln = 0; /* init model field */ for (i = 0; i < 12; i++) rec->rgears[i] = 0; /* init gear array */ rec->rtorqsw = 0; /* init torque switch */ for (i = 0; i < 30; i++) rec->rtorqs[i] = 0; /* init torque array */ rec->rcd = 0; /* init Cd */ rec->rarea = 0; /* init area */ goto start; } if (strcmp(&resp,"B") == 0) { savesw = 0; /* do not save entries */ recsw = 0; /* no record available */ torqsw = 0; /* turn off torque switch */ goto start; } if (strcmp(&resp,"H") == 0) { help(HFILE); /* run help function */ goto chkstat; } PAFUNC(6); /* ring bell */ goto chkstat; /* bad resp, retry */ } else { savesw = 0; /* do not save entries */ recsw = 1; /* record found */ } start: aerosw = 0; /* init aero switch */ PAFUNC(3); /* clear screen */ PAUSEP(&pPERF1,0); /* bring panel into use */ /*********************************************************************/ /* */ /* The main body of the program starts here. The first screen is */ /* displayed, and the user enters the report title and the tire */ /* dimensions. The gears used may be selected by picking a standard*/ /* model or by entering each gear directly. The torque values */ /* are confirmed or entered, and, finally, the cross-sectional */ /* area and coefficient of drag are entered. The torque and */ /* areodynamic values are optional. The help screen may be */ /* displayed at any time by pressing F5, and erased by pressing F5 */ /* again. The program may be ended by pressing Esc from the first */ /* screen (pressing Esc from any other screen returns the user to */ /* the previous screen). */ /* */ /*********************************************************************/ if (recsw) { /* record found */ if (rec->rmodeln == 0) { /* standard model not used */ j = 6; /* first gear field */ for (i = 0; i < 12; i++,j++) { /* copy gear values */ fldptr = pPERF1.faPERF1[j]; /* point to field cntrl blk*/ fp = fldptr->adatablock; /* point to data area */ sprintf(fp,"%-2d",rec->rgears[i]); } } else { sprintf(&PMODEL,"%-2d",rec->rmodeln); /* store in screen */ } } startpgm: PANELS(pdisp); /* display fixed data */ PANELS(ppadf); /* pad fields with fill char */ PANELS(pshow); /* display input fields */ PAMSGE("F5 = Help Esc = Quit"); /* display message */ rdtitle: for (;;) { rc = PANELF(freadh,&fTITLE); /* read title */ switch (rc) { case 0: /* normal read */ case 1: /* only CR entered */ case 5: /* cursor down */ case 6: /* tab */ PANELF(funfil,&fTITLE); /* change _ to blank */ goto rdtire; /* read next field */ case 15: /* F5 */ help(HTITLE); /* run help function */ continue; /* loop back */ case 2: /* escape */ goto endpgm; /* quit */ default: /* if anything else */ PAFUNC(6); /* ring bell */ continue; /* loop back */ } } rdtire: i = 2; /* set index for field array */ for (; i < 5; i++) { fldptr = pPERF1.faPERF1[i]; /* point to fcb */ rc = PANELF(freadh,fldptr); /* read tire width field */ switch (rc) { case 0: /* normal read */ case 1: /* CR only */ if (atoi(fldptr->adatablock) == 0) { /* no zeroes */ PAFUNC(6); /* ring bell */ i -= 1; /* do not incr */ continue; /* loop back */ } continue; /* read next field */ case 3: /* cursor left from fld home */ case 4: /* cursor up keyed */ if (i <= 2) goto rdtitle; /* re-read title field */ i -= 2; /* back up to previous fld */ continue; /* read that field */ case 15: /* F5 */ help(HWIDTH); /* run help function */ i -= 1; /* do not incr */ continue; /* loop back */ case 2: /* escape */ goto endpgm; /* quit */ default: /* if anything else */ PAFUNC(6); /* ring bell */ i -= 1; /* do not incr */ continue; /* loop back */ } } rdmodel: for (;;) { rc = PANELF(freadh,&fMODEL); /* read model number field */ switch (rc) { case 0: /* normal read */ case 1: /* CR only */ PANELF(funfil,&fMODEL); /* change _ to blank */ mod = atoi(MODEL); /* convert to integer */ if (mod == 0) { /* not standard */ m928sw = 0; /* turn off 928 switch */ gptr = &stndardg[0]; /* point to structure */ if (recsw) /* record retrieved */ rec->rmodeln = mod; /* save in record */ goto rdgear; /* read first gear field */ } if (mod < 1 || mod > 13) { /* model out of range */ PAFUNC(6); /* ring bell */ continue; /* loop back */ } if (mod == 13) m928sw = 1; /* turn on switch */ else m928sw = 0; /* turn off switch */ gptr = &stndardg[mod]; /* point to standard gears */ if (recsw) /* record retrieved */ rec->rmodeln = mod; /* save in record */ goto gearcalc; /* calc gear ratios */ case 5: /* cursor down */ case 6: /* tab keyed */ gptr = &stndardg[0]; /* point to structure */ if (recsw) /* record retrieved */ rec->rmodeln = mod; /* save in record */ goto rdgear; /* read first gear field */ case 3: /* cursor left from fld home */ case 4: /* cursor up keyed */ goto rdtire; /* goto previous field */ case 15: /* F5 */ help(HMODEL); /* run help function */ continue; /* loop back */ case 2: /* escape */ goto endpgm; /* quit */ default: /* if anything else */ PAFUNC(6); /* ring bell */ continue; /* loop back */ } } rdgear: i = 6; /* point to 1st gear numer */ for (j = 0; i < 18; i++,j++) { fldptr = pPERF1.faPERF1[i]; /* point to field cntrl blk */ rc = PANELF(freadh,fldptr); /* read gear value */ switch (rc) { case 0: /* normal read */ case 1: /* CR only */ PANELF(funfil,fldptr); /* change _ to blank */ value = atoi(fldptr->adatablock); /* convert to integer */ if (i != 14) { /* not fifth gear */ if (value <= 0) { /* zero/negative not allowed */ PAFUNC(6); /* ring bell */ i -= 1; /* do not incr i */ j -= 1; /* do not incr j */ continue; /* loop back */ } } if (i == 14 && value == 0) { /* zero means no 5th gear */ gptr->stang[j] = 0; /* store zero in array */ rec->rgears[j] = 0; /* store in record */ i += 1; /* incr past 5th denom */ j += 1; /* incr past 5th denom */ continue; /* loop back */ } gptr->stang[j] = value; /* store in array */ rec->rgears[j] = value; /* store in record */ continue; /* read next field */ case 3: /* cursor left from fld home */ case 4: /* cursor up keyed */ if (i == 6) goto rdmodel; /* goto previous field */ i -= 2; /* adjust i */ j -= 2; /* adjust j */ continue; /* loop back */ case 15: /* F5 */ help(HGEAR); /* run help function */ i -= 1; /* do not incr */ j -= 1; /* indicies */ continue; /* loop back */ case 2: /* escape */ goto endpgm; /* quit */ default: /* if anything else */ PAFUNC(6); /* ring bell */ i -= 1; /* do not incr */ j -= 1; /* indicies */ continue; /* loop back */ } } /*********************************************************************/ /* */ /* The user is asked if this is a 928 gearbox. If so, then the */ /* entered ratios must be multiplied by the 5th gear ratio. */ /* */ /*********************************************************************/ for (;;) { PAFUNC(6); /* ring bell */ strcpy(&msg,"Is this a 928 (Y/N)? "); /* build message */ strcpy(&resp,"N"); /* init response */ strcat(&msg,&resp); /* concatenate response */ PAMSGE(msg); /* display message */ PAANSW(resp,crreq+echo+upper); /* default is no */ if ((strcmp(&resp,"Y")) == 0) { m928sw = 1; /* turn on 928 switch */ break; } if ((strcmp(&resp,"N")) == 0) { m928sw = 0; /* turn on 928 switch */ break; } } /*********************************************************************/ /* */ /* The gear ratios are calculated from the gear values, with the */ /* resulting doubles stored in the array gratio[]. */ /* */ /*********************************************************************/ gearcalc: if (m928sw) { numer5 = gptr->stang[8]; /* 5th gear numerator */ denom5 = gptr->stang[9]; /* 5th gear denominator */ } for (i = 0,j = 0; i < 6; i++) { /* calculate gear ratios */ if (gptr->stang[j] == 0) { /* no more gears */ j = 10; /* skip to final drive */ continue; /* loop again */ } numer = gptr->stang[j]; /* get numerator from array */ denom = gptr->stang[j+1]; /* get denom from array */ if (m928sw == 1 && i < 5) { numer = (numer * denom5); /* multiply by 5th denom */ denom = (denom * numer5); /* multiply by 5th numer */ } gratio[i] = (((double) numer) / ((double) denom)); j += 2; /* incr to next pair */ } /*********************************************************************/ /* */ /* The tire dimensions are converted to floating point numbers, */ /* and the final drive ratio is retrieved from the gratio array. */ /* */ /*********************************************************************/ twidth = atof(&WIDTH); /* convert to float */ tsect = atof(&SECT); /* convert to float */ tdia = atof(&DIA); /* convert to float */ fdratio = gratio[5]; /* set to rear end ratio */ /*********************************************************************/ /* */ /* If the tire width is less than 20, the program assumes that the */ /* dimensions are non-metric, and makes the necessary converstions. */ /* */ /*********************************************************************/ if (twidth < 20) { /* assume using inches */ ar = ((tsect - tdia) / 2.0) / twidth; /* calc aspect ratio */ ewidth = twidth; /* store for printing */ twidth = twidth * 25.4; /* convert inches to mm */ } else { ar = (tsect / 100.0); /* calc aspect ratio */ } if (gptr->stang[8] != 0) { /* fifth gear used */ maxg = 5; /* five gears */ } else { maxg = 4; /* five gears */ } for (rpm = 1000,j = 0; rpm <= 8000; j++) { /* 1000-8000 rpm */ for (i= 0; i < maxg; i++) { /* for each gear */ grat = gratio[i]; mptr = &mphrpm[i]; /* point to gmph structure */ rpmile = (20168.0 / (((twidth * ar) / 12.7) + (tdia - 0.62))); mptr->gmph[j] = (((rpm * grat * fdratio) / rpmile) * 60.0); } rpm += 200; /* increment rpm */ } /*********************************************************************/ /* */ /* A screen is displayed to input the torque values for each rpm */ /* from 2000 to 7800. */ /* */ /*********************************************************************/ PAFUNC(3); /* clear screen */ PAUSEP(&pPERF3,0); /* bring panel into use */ if (recsw) { /* record found */ if (data_buf.rtorqsw) { torqsw = 1; /* turn on torque switch */ for (i = 1; i <= 30; i++) { /* copy torque values */ fldptr = pPERF3.faPERF3[i]; /* point to field cntrl blk */ fp = fldptr->adatablock; /* point to data field */ sprintf(fp,"%-5.1f",rec->rtorqs[i-1]); torq[i-1] = data_buf.rtorqs[i-1]; } } else torqsw = 0; /* turn off torque switch */ } PANELS(pdisp); /* display fixed data */ PANELS(ppadf); /* pad fields with fill char */ PANELS(pshow); /* display input fields */ if (torqsw) /* torque values available */ PAMSGE("F1 = Use Defaults F5 = Help Esc = Quit"); /* message*/ else PAMSGE("F5 = Help Esc = Quit"); /* display message */ maxtorq = 0; /* init maximum torque */ for (i = 1; i <= 30; i++) { /* read all 30 fields */ fldptr = pPERF3.faPERF3[i]; /* point to fcb */ rc = PANELF(freadh,fldptr); /* read torque value */ switch (rc) { case 0: /* normal read */ case 1: /* CR only */ torq[i-1] = (float) atof(fldptr->adatablock); rec->rtorqs[i-1] = torq[i-1]; /* copy to record */ if (torq[i-1] > maxtorq) maxtorq = torq[i-1]; /* new max */ if (torq[i-1] == 0) { /* zero not allowed */ if (i == 1 || i == 30) { /* not allowed for 1st/last */ PAFUNC(6); /* ring bell */ i -= 1; /* do not incr */ continue; /* loop back */ } } continue; /* read next field */ case 3: /* cursor left from fld home */ case 4: /* cursor up keyed */ if (i == 1) { /* at first field - invalid */ i -= 1; /* adjust for incr */ PAFUNC(6); /* ring bell */ continue; /* go back to for loop */ } i -= 2; /* back up to previous fld */ continue; /* read that field */ case 11: /* F1 */ if (! torqsw) { /* defaults not available */ i -= 1; /* adjust for incr */ PAFUNC(6); /* ring bell */ continue; /* go back to for loop */ } i = 99; /* set past max loop value */ continue; /* loop back */ case 15: /* F5 */ help(HTORQ); /* run help function */ i -= 1; /* do not incr */ continue; /* loop back */ case 2: /* escape */ torqsw = 0; /* do not use torque values */ rec->rtorqsw = 0; /* copy to record */ goto chkprt; /* forget shift points */ default: /* if anything else */ PAFUNC(6); /* ring bell */ i -= 1; /* do not incr */ continue; /* loop back */ } } torqsw = 1; /* torque values entered */ rec->rtorqsw = 1; /* store in record */ /*********************************************************************/ /* */ /* The torque array is checked for zero values. If found, then the */ /* proper values are interpolated as a straight line between points */ /* */ /*********************************************************************/ for (i = 0; i < 30; i++) { if (torq[i] == 0) { /* zero entry found */ k = i; /* save last entry */ j = 0; /* clear counter */ while (torq[i] == 0) { /* count number of 0 entries */ j++; /* incr count */ i++; /* incr array ptr */ } incr = ((torq[i] - torq[k-1]) / (j + 1)); /* calc increment */ for (; k < i; k++) { torq[k] = (torq[k-1] + incr); /* calc each inter value */ rec->rtorqs[k] = torq[k]; /* store in record */ } } } rpm = 2000; /* init rpm */ for (i = 0; i < 30; i++) { if (maxtorq <= 40) /* assume metric torque */ hp[i] = (0.001374 * torq[i] * rpm); /* calc hp */ else hp[i] = (0.00019 * torq[i] * rpm); /* calc hp */ rpm += 200; /* incr rpm */ } /*********************************************************************/ /* */ /* The shift points are calculated from the torque values and the */ /* arrays of the speeds in each gear. */ /* */ /*********************************************************************/ for (i = 0; i < (maxg - 1); i++) { /* for each gear step */ mptrl = &mphrpm[i]; /* ptr to lower gear array */ mptrh = &mphrpm[i+1]; /* ptr to higher gear array */ for (j = 0,k = 15; j <= 29; k++) { mphl = mptrl->gmph[k]; /* mph in lower gear */ while (mptrh->gmph[j] <= mphl) j++; /* incr j until > mphl */ j -= 1; /* adjust pointer */ if (torq[k-5] <= torq[j-5]) break; /* torque > lower gear */ j = 0; /* reset j */ } shift[i] = 1000 + (200 * k); /* calculate rpm at shift pt */ } /*********************************************************************/ /* */ /* A screen is displayed to input the coefficient of drag and the */ /* cross-sectional area. */ /* */ /*********************************************************************/ PAFUNC(3); /* clear screen */ PAUSEP(&pPERF5,0); /* bring panel into use */ if (recsw) { /* record found */ if (data_buf.rcd != 0) sprintf(&PCD,"%-4.2f",rec->rcd); /* copy to screen */ if (data_buf.rarea != 0) sprintf(&PAREA,"%-5.2f",rec->rarea); /* copy to screen */ } PANELS(pdisp); /* display fixed data */ PANELS(ppadf); /* pad fields with fill char */ PANELS(pshow); /* display input fields */ for (;;) { PAMSGE("F5 = Help Esc = Quit"); /* display message */ rc = PANELS(pread); /* point to fcb */ switch (rc) { case 0: /* normal read */ case 1: /* CR only */ rec->rcd = (float) atof(&PCD); rec->rarea = (float) atof(&PAREA); cd = rec->rcd; area = rec->rarea; if ((cd == 0) || (area == 0)) { PAFUNC(6); /* ring bell */ PAMSGE("Entries cannot be zero or blank - press any key"); ki(); continue; } if (cd >= 1) { PAFUNC(6); /* ring bell */ PAMSGE("Drag coefficient must be less than 1 - press any key"); ki(); continue; } aerosw = 1; /* turn on aero switch */ goto calchpr; case 15: /* F5 */ help(HAERO); /* run help function */ continue; /* loop back */ case 2: /* escape */ aerosw = 0; /* do not use aero values */ goto chkprt; /* forget shift points */ default: /* if anything else */ PAFUNC(6); /* ring bell */ continue; /* loop back */ } } calchpr: mptr = &mphrpm[maxg-1]; /* point to top gear array */ for (i = 0,j = 5; i < 30; i++,j++) { v = mptr->gmph[j]; /* get speed */ hpr[i] = (float) ((0.00000681 * cd * area * (pow(v,3.0))) + (0.088 * v)); } /*********************************************************************/ /* */ /* The performance summary chart is printed. */ /* */ /*********************************************************************/ chkprt: PAFUNC(3); /* clear screen */ rc = pcpgs(0); /* retrieve printer status */ if (rc ^ 0x9000) { PAFUNC(6); /* ring bell */ PAMSGE("PRINTER NOT AVAILABLE - PRESS ENTER WHEN READY OR Esc TO ABORT "); rc = PAANSW(" "); /* get answer */ if (rc == 2) { /* Esc pressed - no printout */ prtsw = 0; /* turn off print switch */ goto prtchrt; /* print to screen */ } else goto chkprt; } else prtsw = 1; prtchrt: PAFUNC(3); /* clear screen */ printf("\nPrinting performance summary chart ... "); if (prtsw) lprintf("\n PORSCHE PERFORMANCE SUMMARY\n"); else printf("\n PORSCHE PERFORMANCE SUMMARY\n"); for (i = 0; i < 70; i++) ctitle[i] = ' '; /* init title field */ ctitle[i] = '\0'; /* put in null terminator */ strcen(&TITLE,&ctitle); /* center title */ if (prtsw) lprintf("\n %s\n\n",ctitle); else printf("\n %s\n\n",ctitle); if (prtsw) lprintf(" MPH at RPM for following parameters:\n"); else printf(" MPH at RPM for following parameters:\n"); if (twidth < 20.0) { /* assume size in inches */ if (prtsw) lprintf("\n Tire size: %.1f x %.1f x %.0f\n",ewidth,tsect,tdia); else printf("\n Tire size: %.1f x %.1f x %.0f\n",ewidth,tsect,tdia); } else { dwidth = atoi(&WIDTH); /* convert to int */ dsect = atoi(&SECT); /* convert to int */ ddia = atoi(&DIA); /* convert to int */ if (prtsw) lprintf("\n Tire size: %d/%d-%d\n",dwidth,dsect,ddia); else printf("\n Tire size: %d/%d-%d\n",dwidth,dsect,ddia); } if (prtsw) lprintf("\n First gear: %d:%d",gptr->stang[0],gptr->stang[1]); else printf("\n First gear: %d:%d",gptr->stang[0],gptr->stang[1]); if (prtsw) lprintf(" Fourth gear: %d:%d",gptr->stang[6],gptr->stang[7]); else printf(" Fourth gear: %d:%d",gptr->stang[6],gptr->stang[7]); if (prtsw) lprintf("\n Second gear: %d:%d",gptr->stang[2],gptr->stang[3]); else printf("\n Second gear: %d:%d",gptr->stang[2],gptr->stang[3]); if (gptr->stang[8] != 0) { /* fifth gear used */ if (prtsw) lprintf(" Fifth gear: %d:%d",gptr->stang[8],gptr->stang[9]); else printf(" Fifth gear: %d:%d",gptr->stang[8],gptr->stang[9]); } else { if (prtsw) lprintf("\n"); /* skip to next line */ else printf("\n"); /* skip to next line */ } if (prtsw) lprintf("\n Third gear: %d:%d",gptr->stang[4],gptr->stang[5]); else printf("\n Third gear: %d:%d",gptr->stang[4],gptr->stang[5]); if (prtsw) lprintf(" Final drive: %d:%d\n",gptr->stang[10],gptr->stang[11]); else printf(" Final drive: %d:%d\n",gptr->stang[10],gptr->stang[11]); if (prtsw) lprintf("\n\n RPM 1st 2nd 3rd 4th"); else printf("\n\n RPM 1st 2nd 3rd 4th"); if (gptr->stang[8] != 0) { if (prtsw) lprintf(" 5th"); else printf(" 5th"); } if (torqsw) { if (prtsw) { lprintf(" Torque"); /* column heading */ lprintf(" HP"); /* column heading */ if (aerosw) lprintf(" HPr\n"); /* column heading */ } else { printf(" Torque"); /* column heading */ printf(" HP"); /* column heading */ if (aerosw) printf(" HPr\n"); /* column heading */ } } else { if (prtsw) lprintf("\n"); else printf("\n"); } for (rpm = 1000,j = 0; rpm <= 8000; j++) { /* 1000-8000 rpm */ if (prtsw) lprintf("\n %d",rpm); /* print rpm column */ else printf("\n %d",rpm); /* print rpm column */ for (i= 0; i < maxg; i++) { /* for each gear */ mptr = &mphrpm[i]; /* point to gmph structure */ if (prtsw) lprintf(" %5.1f",mptr->gmph[j]); else printf(" %5.1f",mptr->gmph[j]); } if (torqsw) { if (rpm >= 2000 && rpm < 8000) { if (prtsw) { lprintf(" %4.1f",torq[j-5]); lprintf(" %3.0f",hp[j-5]); if (aerosw) lprintf(" %3.0f",hpr[j-5]); } else { printf(" %4.1f",torq[j-5]); printf(" %3.0f",hp[j-5]); if (aerosw) printf(" %3.0f",hpr[j-5]); } } } rpm += 200; /* increment rpm */ } if (prtsw) lprintf("\n"); /* print nl */ else printf("\n"); /* print nl */ if (torqsw) { if (prtsw) lprintf("\n Shift pts: "); /* print line */ else printf("\n Shift pts: "); /* print line */ for (i = 0; i < (maxg - 1); i++) { if (prtsw) lprintf(" %d ",shift[i]); /* print value in array */ else printf(" %d ",shift[i]); /* print value in array */ } } endshift: if (prtsw) { lprintf("\n\n Compliments of EUROCAR-WERK"); lprintf("\n 661-6428"); } if (prtsw) { lprintf("\n\014"); /* print final nl, form feed */ } else { printf("\n\nPress any key ... \n"); /* display message */ cget(); /* wait for key press */ } PAFUNC(3); /* clear screen */ PAUSEP(&pPERF1,0); /* bring panel into use */ goto startpgm; /* rerun */ endpgm: /*********************************************************************/ /* */ /* If the file is available, and the record is not already in the */ /* file, then the record is inserted in the file. */ /* */ /*********************************************************************/ if (savesw) { /* save values */ for (i = 0; i < 15; i++) rec->reserved[i] = NULL; /* pad reserved area with 0 */ status = BTRIEVE(b_insert,pos_blk,&data_buf,&data_buf,0); if (status != 0) { PAMSGE("Could not save in file - PRESS ANY KEY "); ki(); } } if (recsw) { /* update values */ for (;;) { strcpy(&msg,"Do you want to save values in a new record (Y/N)? "); strcpy(&resp,"N"); /* init response */ strcat(&msg,&resp); /* concatenate response */ PAMSGE(&msg); PAANSW(&resp,crreq+echo+upper); /* wait for answer */ if ((strcmp(&resp,"Y")) == 0) { strcpy(&msg,"Enter year: "); /* display prompt */ strcat(&msg,&PYEAR); /* concatenate field */ PAMSGE(&msg); /* display message */ PAANSW(&PYEAR,crreq+echo); /* wait for reply */ strncpy(&data_buf,&PYEAR,2); /* copy to record */ strcpy(&msg,"Enter model: "); /* display prompt */ strcat(&msg,&PMODEL); /* concatenate field */ PAMSGE(&msg); /* display message */ PAANSW(&PMODEL,crreq+echo+upper); /* wait for reply */ strncpy(&data_buf,&PMODEL,2); /* copy to record */ strcpy(&msg,"Enter id: "); /* display prompt */ strcat(&msg,&PID); /* concatenate field */ PAMSGE(&msg); /* display message */ PAANSW(&PID,crreq+echo+upper); /* wait for reply */ strncpy(&data_buf,&PMODEL,2); /* copy to record */ for (i = 0; i < 15; i++) rec->reserved[i] = NULL; /* pad reserved area with 0 */ status = BTRIEVE(b_insert,pos_blk,&data_buf,&data_buf,0); if (status != 0) { PAMSGE("Could not add to file - PRESS ANY KEY "); ki(); } break; } if ((strcmp(&resp,"N")) == 0) { strcpy(&msg,"Update this record (Y/N)? "); strcpy(&resp,"N"); /* init response */ strcat(&msg,&resp); /* concatenate field */ PAMSGE(&msg); /* display message */ PAANSW(&resp,crreq+echo+upper); /* wait for reply */ if ((strcmp(&resp,"Y")) == 0) { for (i = 0; i < 15; i++) rec->reserved[i] = NULL; /* pad reserved with 0 */ status = BTRIEVE(b_upd,pos_blk,&data_buf,&data_buf,0); if (status != 0) { PAMSGE("Could not add to file - PRESS ANY KEY "); ki(); } } break; } } } mv_csr(0,0,&wn0); /* put cursor at top corner */ PAFUNC(3); /* clear screen */ if (filesw) { status = BTRIEVE(b_close,pos_blk,&data_buf,&data_buf,0); if (status) printf("\nCould not close PPERFORM.DAT"); else printf("\nPPERFORM.DAT closed"); if (btrstop) { /* stop BTRIEVE */ status = BTRIEVE(b_stop,pos_blk,&data_buf,key1_buf,0); if (status == 0) printf("\nBTRIEVE Terminated"); } } PAFUNC(2); /* send termination sequence */ if (oldmode >= 0 && oldmode <= 7) /* mode valid */ pcvsvm(oldmode); /* reset video mode */ exit(); } /*********************************************************************/ /* */ /* The bw_list function will read all the entries in the PPERFORM */ /* data file equal to or greater than the model requested and */ /* display them in the help window. */ /* */ /*********************************************************************/ bw_list() { int i,j,k; /* ASCII code returned */ int r,c; /* row,column */ int error,status; /* return from functions */ char dmodel[13]; /* string value of model */ char skey[13]; /* string value of key */ int nrecs; /* number of records */ char *p; /* pointer to chars */ char *malloc(); /* returns char * */ error = sav_wi(&wn0); /* save window 0 */ if (error) { PAMSGE("Insufficient memory for list function - PRESS ENTER "); PAANSW(" ",crreq); /* wait for response */ return(0); } set_wn(&wn1); /* put help window on screen */ PAMSGE("PRESS ANY KEY TO RE-ENTER YOUR YEAR, MODEL AND ID"); status = BTRIEVE(b_geteq,pos_blk,&data_buf,&key1_buf,1); for (i = 0; i < 12; i++) skey[i] = key1_buf[i]; skey[i] = '\0'; if (status != 0) { mv_csr(1,1,&wn1); v_st("No entries found for ",&wn1); v_st(&skey,&wn1); v_st(" - press any key",&wn1); ki(); cls(); unsav_wi(&wn0); return(0); } mv_csr(1,1,&wn1); /* set cursor */ v_st("The following entries are in the file for your model:",&wn1); r = 3; /* init row */ c = 5; /* init column */ j = 0; /* init array index */ nrecs = 0; /* init num of records */ while (status != 9) { if (j == 25) break; /* room for 25 entries */ if ((p = malloc(29)) == NULL) break; /* get storage or quit */ lineptr2[j] = p; /* store addr in array */ for (i = 0,k = 0; i < 2; i++,k++) /* copy year */ *p++ = data_buf.rkey[k]; *p++ = ' '; *p++ = ' '; for (i = 0; i < 12; i++,k++) { /* copy model */ *p++ = data_buf.rkey[k]; dmodel[i] = data_buf.rkey[k]; } *p++ = ' '; *p++ = ' '; for (i = 0; i < 10; i++,k++) /* copy id */ *p++ = data_buf.rkey[k]; *p = '\0'; /* end-of-string */ if (strcmp(&dmodel,&skey) != 0) break; status = BTRIEVE(b_getnx,pos_blk,&data_buf,&key1_buf,1); nrecs += 1; /* incr nrecs */ j += 1; /* incr j */ } ki(); /* wait for key press */ cls(); /* clear screen */ unsav_wi(&wn0); /* restore screen */ } /*********************************************************************/ /* */ /* The help function uses the WINDOWS FOR C functions to display */ /* the help text file on the screen. The number passed to the */ /* function is used to start the display at a particular line in */ /* the file. */ /* */ /*********************************************************************/ help(msg) int msg; /* message number */ { if (vmode ^ 0x0007) /* color mode */ color_wn(BLACK,WHITE,&wn1); /* set colors */ PAMSGE("Pg Dn = Next Page Pg Up = Previous Page F5 = End Help"); frp->wfr = msg; /* start at msg in file */ vs_mf(-63,&wn1); return(0); }