/*MortCalc.c v2.5 - Michel Laliberté, août 1990 .KEY source/a cc +L +fi.c ln .o -lma32 -lc32 /* #include #include #include #include #include #include #include #include #include #include #include #include */ #define U_ARGS(a) () #include "mc26.h" extern struct WBStartup *WBenchMsg; struct IntuitionBase *IntuitionBase; struct GfxBase *GfxBase; struct IconBase *IconBase; struct Window *OpenWindow(); double peryear[13], compound[13], value[8]; char valstr[22][33], entree[25], tab[25], tab1[25]; double principal, r1, rate, payment, balance, months, years, an, mo, val; int indice, cal, site, NextArg, yrs, mts, mois, indsel; BOOL suff, zero, print, capital, go, msg, mx, can, fr, screen, quit_flag; APTR obj0; struct DiskObject *diskobj; char **findtools U_ARGS((char *,BPTR)); main(argc, argv) /* départ - initialisation des valeurs */ int argc; char *argv[]; { int count, i; struct WBArg *wbarg; char **toolptr,*name,lookup[4]; peryear[1] = 12; peryear[2] = 6; peryear[3] = 4; peryear[4] = 3; peryear[6] = 2; peryear[12] = 1; compound[1] = 1; compound[2] = 2; compound[3] = 3; compound[4] = 4; compound[6] = 6; compound[12] = 12; value[0] = 1; value[1] = 10000; value[2] = 10; value[3] = 120; value[4] = 0; value[5] = 132.15; value[6] = 5858.09; cal = 5; site = 1; /* valeurs de démarrage par défaut */ indice = 5;strcpy(entree,Gadget15SIBuff); obj0 = (APTR)&Gadget11; if (argv[1][0] == '?') /* tableau d'aide - CLI */ { printf("\nMortCalc v2.5 - M. Laliberté, August 1990\n\n"); printf("USAGE: %s [-c -f -s] \n\n", argv[0]); printf(" %s ? : help screen\n",argv[0]); printf("Options:\n"); printf(" -c : Compounded semiannually (Canada) \n"); printf(" (default: USA, compounded monthly) \n"); printf(" -f : en français (default: English)\n"); printf(" -s : display raw data to std output (CLI)\n\n"); exit(0); } else if (argc) /* options du CLI */ { for (NextArg=1; NextArg pr_CurrentDir); else /* lancé du Workbench */ { /* lecture du ToolType de l'icône */ wbarg = &(WBenchMsg->sm_ArgList[WBenchMsg->sm_NumArgs-1]); toolptr = findtools(wbarg->wa_Name,wbarg->wa_Lock); strcpy(lookup,"ARG1"); count = 0; for (i=0; i < 4; i++) { if ((name=FindToolType(toolptr,lookup)) != NULL) { if (!strcmp (name,"CAN")) can = TRUE; else if (!strcmp (name,"FR")) fr = TRUE; } lookup[3]++; } } if(can) /* option CANADA */ { Gadget6.Flags = SELECTED; Gadget9.Flags = NULL; value[6] = 5724.04; value[5] = 131.03; site = 6; strcpy(Gadget15SIBuff,"$ 131.03 "); strcpy(Gadget16SIBuff,"$ 5724.04 "); strcpy(Gadget10SIBuff, "6 "); } if(fr) /* option FRANCAIS */ { strcpy (valstr[2], "Taux "); strcpy (valstr[3], "Période "); strcpy (valstr[4], "Solde "); strcpy (valstr[5], "Paiement "); strcpy (valstr[6], "Entrer une valeur positive"); strcpy (valstr[7], "Impossible! Paiement trop bas"); strcpy (valstr[8], "Solde nul! Paiement trop élevé"); strcpy (valstr[10], " ans"); strcpy (valstr[12], "Capitalisé sur %d mois"); strcpy (valstr[13], "calculé"); strcpy (valstr[14], "selectionné"); strcpy (valstr[17], ""); strcpy (valstr[18], "S.V.P. ouvrir l'imprimante"); strcpy (valstr[19], "Fin de l'impression"); strcpy (valstr[20], "Intérêts "); strcpy (valstr[21], "Intérêts supérieurs au paiement!"); strcpy(Gadget13SIBuff," 10 ans 0 mo."); strcpy(Gadget17SIBuff,"Bienvenue! Paiement sélectionné"); IText10.IText = (UBYTE *)"Intérêts"; IText11.IText = (UBYTE *)"Calculateur d'hypothèques v2.5 »**« M. Laliberté, août 1990"; IText12.IText = (UBYTE *)"MESSAGE:"; IText15.IText = (UBYTE *)"Capitalisé sur"; IText16.IText = (UBYTE *)"mois"; IText17.IText = (UBYTE *)"Taper Amiga(droite)-X pour vider une boîte"; IText17.LeftEdge = 66; IText8.IText = (UBYTE *)"Taux"; IText7.IText = (UBYTE *)"Période"; IText6.IText = (UBYTE *)"Solde"; IText6.LeftEdge = 13; IText5.IText = (UBYTE *)"Paiement"; IText3.IText = (UBYTE *)"Calcul"; IText3.LeftEdge = 20; IText2.IText = (UBYTE *)"Imprimante"; IText2.LeftEdge = 10; } else /* option ANGLAIS par défaut */ { strcpy (valstr[2], "Rate "); strcpy (valstr[3], "Period "); strcpy (valstr[4], "Balance "); strcpy (valstr[5], "Payment "); strcpy (valstr[6], "Enter a positive value"); strcpy (valstr[7], "No way! Payment too low"); strcpy (valstr[8], "No balance! Payment too high"); strcpy (valstr[10], " yrs"); strcpy (valstr[12], "Compounded over %d months"); strcpy (valstr[13], "computed"); strcpy (valstr[14], "selected"); strcpy (valstr[17], "All entries refreshed"); strcpy (valstr[18], "Print selected - Open printer"); strcpy (valstr[19], "Close printer selected"); strcpy (valstr[20], "Interest "); strcpy (valstr[21], "Interest exceeds payment!"); } strcpy (valstr[0], "\0"); strcpy (valstr[1], "Principal "); strcpy (valstr[9], " % "); strcpy (valstr[11], " mo."); strcpy (valstr[15], "U.S.A. "); strcpy (valstr[16], "Canada "); OpenAll(); /* ouvre fenêtre MortCalc */ cleanup(); /* sortie */ } char **findtools(name,lock) /* Pour la lecture du Tool Type */ char *name; BPTR lock; { BPTR olddir; char **tools = NULL; if(lock == NULL) return (NULL); olddir = (BPTR)CurrentDir(lock); if((diskobj=GetDiskObject(name)) != NULL) tools=diskobj->do_ToolTypes; /* CurrentDir(olddir); */ return(tools); } PrintStr(Window) /* Envoie les valeurs au CLI et à l'imprimante */ APTR Window; { FILE *printer; int i; if (screen) { printf(valstr[12],site); printf("\n"); printf("%s= $%lf \n",valstr[1],value[1]); printf("%s = %lf%s\n",valstr[2],value[2],valstr[9]); printf("%s = %lf%s\n",valstr[3],value[3],valstr[11]); printf("%s = $%lf \n",valstr[4],value[4]); printf("%s = $%lf \n",valstr[5],value[5]); printf("%s= $%lf \n\n",valstr[20],value[6]); } if (print) /* à l'imprimante */ { printer = fopen("prt:", "w"); if (printer == NULL) { DisplayBeep(NULL); sprintf(Gadget17SIBuff,"%s",valstr[6]); RefreshGList(&Gadget17,Window,NULL,1); } fprintf(printer,"\t\t"); fprintf(printer,valstr[12],site);fprintf(printer,"\n"); mts = (int) (value[3]+0.02); yrs = mts/12; mois = (int) (value[3]-yrs*12); fprintf(printer,"\t\t%s= $%9.2lf \n",valstr[1],value[1]); fprintf(printer,"\t\t%s = %3.3lf%s\n",valstr[2],value[2],valstr[9]); fprintf(printer,"\t\t%s = %d%s %d%s\n",valstr[3],yrs,valstr[10],mois,valstr[11]); fprintf(printer,"\t\t%s = $%9.2lf \n",valstr[4],value[4]); fprintf(printer,"\t\t%s = $%9.2lf \n",valstr[5],value[5]); fprintf(printer,"\t\t%s= $%9.2lf \n",valstr[20],value[6]); fprintf(printer, "\n\n\n\n\n\n"); fclose(printer); } } fprin() /* calcul PRINCIPAL */ { value[1] = (balance+payment*(pow(r1, months)-1)/rate)/pow(r1,months); } fintr() /* calcul TAUX d'intérêt */ { double r0, r2, r9, p0, p2, p9; int flop; r0 = 0; r1 = exp(75/months); if (r1>2) r1 = 2; rate = r1 - 1; r9 = rate*100; p0 = balance + payment*months - principal; p9 = (balance+payment*(pow(r1,months)-1)/rate)/pow(r1,months)-principal; if (p0 <0 || p9>0) r2 = 0; else { flop = 0; while (abs(r9 - r0) > 0.001) { flop = 1 - flop; if (flop >0) r2 = (r0 + r9)/2; else { r2 = r0 - p0*(r9 - r0)/(p9 - p0); } r1 = pow((1 + r2/100/peryear[site]), (1/compound[site])); rate = r1 - 1; p2 = (balance+payment*(pow(r1, months)-1)/rate)/pow(r1, months)-principal; if(p2 >0 ) { r0 = r2; p0 = p2; } else { r9 = r2; p9 = p2; } } } value[2] = r2; } fper() /* calcul PERIODE d'amortissement */ { value[3] = log((payment-rate*balance)/(payment-rate*principal))/log(r1); } fbal() /* calcul SOLDE */ { value[4] = principal*pow(r1,months) - payment*(pow(r1,months) - 1)/rate; } fpay() /* calcul PAIEMENT */ { value[5] = rate*(principal*pow(r1, months)-balance)/(pow(r1,months)-1); } finterests() /* calcul INTERETS */ { /* value[6] = principal*value[2]/1200; */ value[6] = value[3]*value[5]- (value[1] - value[4]); } parse(string) /* conversion des entiers du tampon PERIODE */ char *string; { int combien, q, p; char ch; double an, mo; an = mo = 0; combien = strlen(string); q = 0; p= 0; ch = '0'; while (q < combien && (string[q] < '0' || string[q] > '9')) { q++; } while (q < combien && ch > '/' && ch < ':') { ch = string[q]; tab[p] = ch; q++; p++; } tab[p] = '\0'; an = atoi(tab); if (q == combien || q > combien) { value[3] = an*12; return; } while (q < combien && (string[q] < '0' || string[q] > '9')) { q++; } p= 0; ch = '0'; while (q < combien && ch > '/' && ch < ':') { ch = string[q]; tab[p] = ch; q++; p++; } tab[p] = '\0'; mo = atoi(tab); value[3] = an*12 + mo; } parsef(string,ind) /* conversion des flottants des autres tampons */ char *string; int ind; { double atof(); int combien, q, p; char ch; combien = strlen(string); q = 0; p= 0; ch = '0'; while (q < combien && (string[q] < '0' || string[q] > '9')) { q++; } while (q < combien && ((ch > '/' && ch < ':') || ch == ',' || ch == '.')) { if (string[q] == ',') q++; tab[p] = string[q];ch = string[q]; q++; p++; } tab[p] = '\0'; value[ind] = atof(tab); } VOID ChangeGadgetState(Win, Gad, State) /* gadgets mutuel. exclusifs */ register struct Window *Win; register struct Gadget *Gad; register BOOL State; { register USHORT GadPos; GadPos = RemoveGadget(Win, Gad); RefreshGList(Gad, Win, NULL, 1); if( State ) if( !(Gad->Flags & SELECTED) ) Gad->Flags |= SELECTED; if( !State ) if (Gad->Flags & SELECTED) Gad->Flags ^= SELECTED; AddGadget(Win, Gad, GadPos); RefreshGList(Gad, Win, NULL, 1); return; } FEntree(win) /* entrer le contenu des boîtes de valeurs */ APTR win; { int ind; site = atoi(Gadget10SIBuff); strcpy(entree,Gadget11SIBuff); ind = 1; parsef (entree,ind); Check(win,ind); strcpy(entree,Gadget12SIBuff); ind = 2; parsef (entree,ind); Check(win,ind); strcpy(entree,Gadget13SIBuff); ind = 3; parse (entree); Check(win,ind); strcpy(entree,Gadget14SIBuff); ind = 4; parsef (entree,ind); Check(win,ind); strcpy(entree,Gadget15SIBuff); ind = 5; parsef (entree,ind); Check(win,ind); } Check(win,ind) /* zéro = erreur */ APTR win; int ind; { APTR gadg; if ((value[ind] <= 0) && ( ind != 4) && (ind != cal)) { DisplayBeep(NULL); sprintf(Gadget17SIBuff,"%s",valstr[6]); RefreshGList(&Gadget17,win,NULL,1); value[ind] = 0; switch (ind) { case 1: gadg = (APTR)&Gadget11; break; case 2: gadg = (APTR)&Gadget12; break; case 3: gadg = (APTR)&Gadget13; break; case 4: gadg = (APTR)&Gadget14; break; case 5: gadg = (APTR)&Gadget15; break; case 6: gadg = (APTR)&Gadget16; break; } zero = 1; FUpdate(win, gadg, ind); ActivateGadget(gadg,win,NULL); } } FUpdate(win, gadg, ind) /* mise à jour d'une boîte de valeurs*/ APTR win; APTR gadg; int ind; { USHORT GadPos; GadPos = RemoveGadget(win, gadg); RefreshGList(gadg,win,NULL,1); switch (ind) { case 0: sprintf(Gadget10SIBuff,"%d",site); break; case 1: sprintf(Gadget11SIBuff,"$ %-9.2lf",value[1]); break; case 2: sprintf(Gadget12SIBuff," %3.3lf%s",value[2],valstr[9]); break; case 3: sprintf(Gadget13SIBuff," %d%s %d%s",yrs,valstr[10],mois,valstr[11]); break; case 4: sprintf(Gadget14SIBuff,"$ %-9.2lf",value[4]); break; case 5: sprintf(Gadget15SIBuff,"$ %-9.2lf",value[5]); break; case 6: sprintf(Gadget16SIBuff,"$ %-9.2lf",value[6]); break; } AddGadget(win, gadg, GadPos); RefreshGList(gadg,win,NULL,1); } Refresh(win) /* rafraîchissement */ APTR win; { APTR gadg; sprintf(Gadget11SIBuff,"$ %-9.2lf",value[1]); sprintf(Gadget12SIBuff," %-3.3lf%s",value[2],valstr[9]); mts = (int) value[3]; yrs = mts/12; mois = (int) (value[3]-yrs*12); sprintf(Gadget13SIBuff," %d%s %d%s",yrs,valstr[10],mois,valstr[11]); sprintf(Gadget15SIBuff,"$ %-9.2lf",value[5]); sprintf(Gadget14SIBuff,"$ %-9.2lf",value[4]); sprintf(Gadget16SIBuff,"$ %-9.2lf",value[6]); RefreshGList(&Gadget11,win,NULL,-1); } FMessage(str,win) /* message de confirmation */ char *str; APTR win; { strcpy(valstr[0],"\0"); strcat(valstr[0],str); strcat(valstr[0],valstr[13]); sprintf(Gadget17SIBuff,"%s",valstr[0]); RefreshGList(&Gadget17,win,NULL,1); } cleanup() /* sortie */ { if(diskobj) { FreeDiskObject(diskobj); diskobj = NULL; } if (GfxBase != NULL) CloseLibrary(GfxBase); if (IconBase != NULL) CloseLibrary(IconBase); if (IntuitionBase != NULL) CloseLibrary(IntuitionBase); exit(0); } OpenAll() /* ouvre fenêtre et boucle principale */ { UWORD code; ULONG class; APTR PrevGadg; APTR gadg; APTR object; USHORT GadPos; struct Window *wG; /* we fetch the RastPort pointer from here */ struct RastPort *rpG; struct IntuiMessage *message; /* the message the IDCMP sends us */ void HandleEvent(); wG = OpenWindow(&NewWindowStructure1); /* open the window */ if ( wG == NULL ) { printf ("Can't open window!\n"); cleanup(); } rpG = wG->RPort; /* get a rastport pointer for the window */ PrintIText(rpG,&IntuiTextList1,0L,0L); /* Print the text if any */ Gadget17.NextGadget = NULL; /* valeurs par défaut et */ Gadget11.GadgetRender = NULL; /* accéleration du rafraîchissement */ Gadget12.GadgetRender = NULL; Gadget13.GadgetRender = NULL; Gadget14.GadgetRender = NULL; Gadget15.GadgetRender = NULL; Gadget16.GadgetRender = NULL; Gadget17.GadgetRender = NULL; ActivateGadget(&Gadget11,wG,NULL); PrevGadg = (APTR)&Gadget5; do { WaitPort(wG->UserPort); while( (message = (struct IntuiMessage *) GetMsg(wG->UserPort) ) != NULL) { code = message->Code; /* MENUNUM */ object = message->IAddress; /* Gadget */ class = message->Class; ReplyMsg(message); if ( class == CLOSEWINDOW ) { quit_flag = TRUE; } if ( class == GADGETUP) { HandleEvent(object,wG); /* lit les gadgets */ if (capital) /* capitalisation CANADA, USA ou autre */ { FUpdate(wG, &Gadget10, 0); if (site == 1) { ChangeGadgetState(wG, (APTR)&Gadget6, FALSE); ChangeGadgetState(wG, (APTR)&Gadget9, TRUE); } else if (site == 6) { ChangeGadgetState(wG, (APTR)&Gadget9, FALSE); ChangeGadgetState(wG, (APTR)&Gadget6, TRUE); } else { ChangeGadgetState(wG, (APTR)&Gadget6, FALSE); ChangeGadgetState(wG, (APTR)&Gadget9, FALSE); } capital = 0; } if (mx) /* ouvre et ferme gadgets mut. exclusifs */ { ChangeGadgetState(wG, PrevGadg, FALSE); ChangeGadgetState(wG, object, TRUE); PrevGadg = object; mx = 0; } if (msg) /* message de sélection */ { strcpy(valstr[0],"\0"); strcat(valstr[0],valstr[indsel]); if (!suff) strcat(valstr[0],valstr[14]); sprintf(Gadget17SIBuff,"%s",valstr[0]); RefreshGList(&Gadget17,wG,NULL,1); msg = 0; suff = 0; ActivateGadget(obj0,wG,NULL); } if (go) /* calcul lancé */ { r1 = pow((value[2]/100/peryear[site] +1 ),(1/compound[site])); rate = r1-1; go = 0; principal = value[1]; months = value[3]; balance = value[4]; payment = value[5]; switch(cal) /* sélection du calcul */ { case 1: /* PRINCIPAL */ fprin(); finterests(); FUpdate(wG, &Gadget16, 6); FMessage(valstr[1],wG); principal = value[1]; FUpdate(wG, &Gadget11, 1); ActivateGadget(&Gadget11,wG,NULL); break; case 2: /* TAUX */ fintr(); if (value[2] <= 0 ) { DisplayBeep(NULL); sprintf(Gadget17SIBuff,"%s",valstr[7]); RefreshGList(&Gadget17,wG,NULL,1); value[2] = 0; FUpdate(wG,&Gadget12,2); ActivateGadget(&Gadget12,wG,NULL); continue; } FMessage(valstr[2],wG); finterests(); FUpdate(wG, &Gadget16, 6); r1 = pow((value[2]/100/peryear[site] +1 ),(1/compound[site])); rate = r1-1; value[7] = value[5]; fpay(); if ((value[7] - 0.01) > value[5]) { DisplayBeep(NULL); sprintf(Gadget17SIBuff,"%s",valstr[21]); RefreshGList(&Gadget17,wG,NULL,1); value[2] = 0; FUpdate(wG,&Gadget12,2); ActivateGadget(&Gadget12,wG,NULL); continue; } value[5] = value[7]; FUpdate(wG, &Gadget12, 2); ActivateGadget(&Gadget12,wG,NULL); break; case 3: /* PERIODE */ fper(); if (value[3] < .001 || value[3] > 9999) { DisplayBeep(NULL); sprintf(Gadget17SIBuff,"%s",valstr[7]); RefreshGList(&Gadget17,wG,NULL,1); value[3] = 0; mts = 0; yrs = 0; mois = 0; FUpdate(wG,&Gadget13,3); ActivateGadget(&Gadget13,wG,NULL); continue; } mts = (int) (value[3]+ 0.02); yrs = mts/ 12; mois = (int) (value[3]-yrs*12); FMessage(valstr[3],wG); finterests(); FUpdate(wG, &Gadget16, 6); FUpdate(wG, &Gadget13, 3); ActivateGadget(&Gadget13,wG,NULL); break; case 4: /* SOLDE */ fbal(); if (value[4] < 0 ) { DisplayBeep(NULL); sprintf(Gadget17SIBuff,"%s",valstr[8]); RefreshGList(&Gadget17,wG,NULL,1); value[4] = 0; FUpdate(wG,&Gadget14,4); ActivateGadget(&Gadget14,wG,NULL); continue; } FMessage(valstr[4],wG); finterests(); FUpdate(wG, &Gadget16, 6); FUpdate(wG, &Gadget14, 4); ActivateGadget(&Gadget14,wG,NULL); break; case 5: /* PAIEMENT */ fpay(); if (value[5] <= 0 ) { DisplayBeep(NULL); sprintf(Gadget17SIBuff,"%s",valstr[7]); RefreshGList(&Gadget17,wG,NULL,1); value[5] = 0; FUpdate(wG,&Gadget15,5); ActivateGadget(&Gadget15,wG,NULL); continue; } FMessage(valstr[5],wG); finterests(); FUpdate(wG, &Gadget16, 6); FUpdate(wG, &Gadget15, 5); ActivateGadget(&Gadget15,wG,NULL); break; } PrintStr(wG); } } } } while (quit_flag == FALSE); CloseWindow(wG); /* on ferme */ } void HandleEvent(object,win) /* lecture des gadgets */ APTR object; APTR win; { if (object == (APTR)&Gadget1) /* bouton PRINCIPAL */ { cal = 1; mx = 1; msg = 1; indsel = 1; } else if (object == (APTR)&Gadget2) /* bouton TAUX */ { cal = 2; mx = 1; msg = 1; indsel = 2; } else if (object == (APTR)&Gadget3) /* bouton PERIODE */ { cal = 3; mx = 1; msg = 1; indsel = 3; } else if (object == (APTR)&Gadget4) /* bouton SOLDE */ { cal = 4; mx = 1; msg = 1; indsel = 4; } else if (object == (APTR)&Gadget5) /* bouton PAIEMENT */ { cal = 5; mx = 1; msg = 1; indsel = 5; } else if (object == (APTR)&Gadget6) /* bouton CANADA */ { site = 6; capital = 1; go = 1; } else if (object == (APTR)&Gadget7) /* bouton IMPRIMER */ { if (print == 1) { print = 0; msg = 1; indsel = 19; } else { print = 1; msg = 1; indsel = 18; } suff = 1; } else if (object == &Gadget8) /* bouton CALCULER */ { FEntree(win); Refresh(win); if (!zero) go = 1; else zero = 0; } else if (object == (APTR)&Gadget9) /* bouton USA */ { site = 1; capital = 1; go = 1; } else if (object == (APTR)&Gadget10) /* boîte Capitalisé ... */ { site = atoi(Gadget10SIBuff); capital = 1; go = 1; } else if (object == &Gadget11) /* boîte PRINCIPAL */ { obj0 = (APTR)object; ActivateGadget(&Gadget12,win,NULL); } else if (object == &Gadget12) /* boîte TAUX */ { obj0 = (APTR)object; ActivateGadget(&Gadget13,win,NULL); } else if (object == &Gadget13) /* boîte PERIODE */ { obj0 = (APTR)object; ActivateGadget(&Gadget14,win,NULL); } else if (object == &Gadget14) /* boîte SOLDE */ { obj0 = (APTR)object; ActivateGadget(&Gadget15,win,NULL); } else if (object == &Gadget15) /* boîte PAIEMENT */ { obj0 = (APTR)object; ActivateGadget(&Gadget11,win,NULL); } }