home *** CD-ROM | disk | FTP | other *** search
/ Chip 2001 Mobile / Chip_Mobile_2001.iso / palm / hobby / pdof / pdof.EXE / pdof.c < prev    next >
C/C++ Source or Header  |  2000-11-27  |  16KB  |  607 lines

  1. /*
  2.  *  PDoF 1.2 Copyright (c) 2000 Matti J. KΣrki
  3.  *
  4.  *  This program is free software; you can redistribute it and/or modify
  5.  *  it under the terms of the GNU General Public License as published by
  6.  *  the Free Software Foundation; either version 2 of the License, or
  7.  *  (at your option) any later version.
  8.  *
  9.  *  This program is distributed in the hope that it will be useful,
  10.  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  11.  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12.  *  GNU General Public License for more details.
  13.  *
  14.  *  You should have received a copy of the GNU General Public License
  15.  *  along with this program; if not, write to the Free Software
  16.  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  17.  */
  18.  
  19. #include <PalmOS.h>
  20. #include <FeatureMgr.h>
  21. #include <FloatMgr.h>
  22. #include "pdof.h"
  23.  
  24. /* Global variables (preferences) */
  25.  
  26. double gFocalLength = 35.0;
  27. double gAperture = 11.0;
  28. double gDistance = 10.0;
  29. int gCoC = 0;
  30.  
  31.  
  32. /****************************************************************************
  33.     The beginning of the PrintDouble section.
  34.  ****************************************************************************/
  35.  
  36. /*
  37.  *  The following code is written by Fred Bayer, the author of LispMe and
  38.  *  modified by Warren Young, the author of f/Calc.
  39.  *
  40.  *  The following section is released as Public Domain. More information
  41.  *  about the original code can be found here:
  42.  *  http://www.lispme.de/lispme/gcc/tech.html
  43.  */
  44.  
  45. #define _DONT_USE_FP_TRAPS_ 1
  46. #include <PalmTypes.h>
  47. #include <PalmCompatibility.h>
  48. #include <CoreTraps.h>
  49. #include <StringMgr.h>
  50.  
  51. void SysTrapFlpLToF(FlpDouble *, Long) SYS_TRAP(sysTrapFlpEmDispatch);
  52.  
  53. /* convert a long to double */
  54. double longToDouble(long l) {
  55.   FlpCompDouble fcd;
  56.   asm("moveq.l %0,%%d2": : "i"(sysFloatEm_d_itod):"d2");
  57.   SysTrapFlpLToF(&fcd.fd, l);
  58.   return fcd.d;
  59. }
  60.  
  61. Long SysTrapFlpFToL(FlpDouble) SYS_TRAP(sysTrapFlpEmDispatch);
  62.  
  63. /* convert a double to long */
  64. long doubleToLong(double d) {
  65.   FlpCompDouble fcd;
  66.   fcd.d = d;
  67.   asm("moveq.l %0,%%d2": : "i"(sysFloatEm_d_dtoi):"d2");
  68.   return SysTrapFlpFToL(fcd.fd);
  69. }
  70.  
  71. void SysTrapBinOp(FlpDouble *, FlpDouble, FlpDouble) SYS_TRAP(sysTrapFlpEmDispatch);
  72.  
  73. /* the same interface is used for all basic arithmetic operations */
  74. double genericDoubleOp(double a, double b, long opcode) {
  75.   FlpCompDouble fcda, fcdb, fcds;
  76.   fcda.d = a;
  77.   fcdb.d = b;
  78.   asm("move.l %0,%%d2": : "g"(opcode):"d2");
  79.   SysTrapBinOp(&fcds.fd, fcda.fd, fcdb.fd);
  80.   return fcds.d;
  81. }
  82.  
  83. /* basic arithmetic operations */
  84. #define addDouble(a,b) genericDoubleOp(a,b,sysFloatEm_d_add)
  85. #define subDouble(a,b) genericDoubleOp(a,b,sysFloatEm_d_sub)
  86. #define mulDouble(a,b) genericDoubleOp(a,b,sysFloatEm_d_mul)
  87. #define divDouble(a,b) genericDoubleOp(a,b,sysFloatEm_d_div)
  88.  
  89. SDWord SysTrapCompare(FlpDouble, FlpDouble) SYS_TRAP(sysTrapFlpEmDispatch);
  90.  
  91. /* compare 2 doubles for equality */
  92. Boolean eqDouble(double a, double b) {
  93.   FlpCompDouble fcda, fcdb;
  94.   fcda.d = a;
  95.   fcdb.d = b;
  96.   asm("moveq.l %0,%%d2": : "i"(sysFloatEm_d_feq):"d2");
  97.   return SysTrapCompare(fcda.fd, fcdb.fd);
  98. }
  99.  
  100. /* compare 2 doubles for less or equal */
  101. Boolean leqDouble(double a, double b) {
  102.   FlpCompDouble fcda, fcdb;
  103.   fcda.d = a;
  104.   fcdb.d = b;
  105.   asm("moveq.l %0,%%d2": : "i"(sysFloatEm_d_fle):"d2");
  106.   return SysTrapCompare(fcda.fd, fcdb.fd);
  107. }
  108.  
  109.  
  110. /**********************************************************************/
  111. /* Formatting parameters                                              */
  112. /**********************************************************************/
  113. #define NUM_DIGITS   15
  114. #define MIN_FLOAT    4
  115. #define ROUND_FACTOR 1.0000000000000005 /* NUM_DIGITS zeros */
  116.  
  117.  
  118. /**********************************************************************/
  119. /* FP conversion constants                                            */
  120. /**********************************************************************/
  121. static double pow1[] = {
  122.   1e256, 1e128, 1e064,
  123.   1e032, 1e016, 1e008,
  124.   1e004, 1e002, 1e001
  125. };
  126.  
  127. static double pow2[] = {
  128.   1e-256, 1e-128, 1e-064,
  129.   1e-032, 1e-016, 1e-008,
  130.   1e-004, 1e-002, 1e-001
  131. };
  132.  
  133. void printDouble(double x, char *s) {
  134.   FlpCompDouble fcd;
  135.   short e, e1, i;
  136.   double *pd, *pd1;
  137.   char sign = '\0';
  138.   short dec = 0;
  139.  
  140.   /*------------------------------------------------------------------*/
  141.   /* Round to desired precision                                       */
  142.   /* (this doesn't always provide a correct last digit!)              */
  143.   /*------------------------------------------------------------------*/
  144.   x = mulDouble(x, ROUND_FACTOR);
  145.  
  146.   /*------------------------------------------------------------------*/
  147.   /* check for NAN, +INF, -INF, 0                                     */
  148.   /*------------------------------------------------------------------*/
  149.   fcd.d = x;
  150.   if ((fcd.ul[0] & 0x7ff00000) == 0x7ff00000)
  151.     if (fcd.fdb.manH == 0 && fcd.fdb.manL == 0)
  152.       if (fcd.fdb.sign)
  153.     StrCopy(s, "[-inf]");
  154.       else
  155.     StrCopy(s, "[inf]");
  156.     else
  157.       StrCopy(s, "[nan]");
  158.   else if (FlpIsZero(fcd))
  159.     StrCopy(s, "0");
  160.   else {
  161.     /*----------------------------------------------------------------*/
  162.     /* Make positive and store sign                                   */
  163.     /*----------------------------------------------------------------*/
  164.     if (FlpGetSign(fcd)) {
  165.       *s++ = '-';
  166.       FlpSetPositive(fcd);
  167.     }
  168.  
  169.     if ((unsigned) fcd.fdb.exp < 0x3ff) {   /* meaning x < 1.0 */
  170.       /*--------------------------------------------------------------*/
  171.       /* Build negative exponent                                      */
  172.       /*--------------------------------------------------------------*/
  173.       for (e = 1, e1 = 256, pd = pow1, pd1 = pow2; e1;
  174.        e1 >>= 1, ++pd, ++pd1)
  175.     if (!leqDouble(*pd1, fcd.d)) {
  176.       e += e1;
  177.       fcd.d = mulDouble(fcd.d, *pd);
  178.     }
  179.       fcd.d = mulDouble(fcd.d, 10.0);
  180.  
  181.       /*--------------------------------------------------------------*/
  182.       /* Only print big exponents                                     */
  183.       /*--------------------------------------------------------------*/
  184.       if (e <= MIN_FLOAT) {
  185.     *s++ = '0';
  186.     *s++ = '.';
  187.     dec = -1;
  188.     while (--e)
  189.       *s++ = '0';
  190.       }
  191.       else
  192.     sign = '-';
  193.     }
  194.     else {
  195.       /*--------------------------------------------------------------*/
  196.       /* Build positive exponent                                      */
  197.       /*--------------------------------------------------------------*/
  198.       for (e = 0, e1 = 256, pd = pow1, pd1 = pow2; e1;
  199.        e1 >>= 1, ++pd, ++pd1)
  200.     if (leqDouble(*pd, fcd.d)) {
  201.       e += e1;
  202.       fcd.d = mulDouble(fcd.d, *pd1);
  203.     }
  204.       if (e < NUM_DIGITS)
  205.     dec = e;
  206.       else
  207.     sign = '+';
  208.     }
  209.  
  210.     /*----------------------------------------------------------------*/
  211.     /* Extract decimal digits of mantissa                             */
  212.     /*----------------------------------------------------------------*/
  213.     for (i = 0; i < NUM_DIGITS; ++i, --dec) {
  214.       Long d = doubleToLong(fcd.d);
  215.       *s++ = d + '0';
  216.       if (!dec)
  217.     *s++ = '.';
  218.       fcd.d = subDouble(fcd.d, longToDouble(d));
  219.       fcd.d = mulDouble(fcd.d, 10.0);
  220.     }
  221.  
  222.     /*----------------------------------------------------------------*/
  223.     /* Remove trailing zeros and decimal point                        */
  224.     /*----------------------------------------------------------------*/
  225.     while (s[-1] == '0')
  226.       *--s = '\0';
  227.     if (s[-1] == '.')
  228.       *--s = '\0';
  229.  
  230.     /*----------------------------------------------------------------*/
  231.     /* Append exponent                                                */
  232.     /*----------------------------------------------------------------*/
  233.     if (sign) {
  234.       *s++ = 'e';
  235.       *s++ = sign;
  236.       StrIToA(s, e);
  237.     }
  238.     else
  239.       *s = '\0';
  240.   }
  241. }
  242.  
  243. /****************************************************************************
  244.     The end of the PrintDouble section.
  245.  ****************************************************************************/
  246.  
  247.  
  248. /*
  249.  *  Calculates a hyper-focal distance. This value is used to
  250.  *  calculate the near and far edges.
  251.  *
  252.  *  folcaLength - Focal Length in millimeters (for example 35.0).
  253.  *  aperture    - Aperture (for example 22.0).
  254.  *  coc         - CoC value. This is 0.033 for 35mm film.
  255.  *                0.06 = 6x6cm film
  256.  *                0.15 = 4x5in film
  257.  */
  258. static double CalcHyperfocalDist(double focalLength,
  259.                  double aperture,
  260.                  double coc) {
  261.   return ((focalLength * focalLength) / (aperture * coc));
  262. }
  263.  
  264. /*
  265.  *  Calculates the near edge.
  266.  *
  267.  *  hyperfocalDist - Use the result of CalcHyperfocalDist().
  268.  *  distOfTarget   - Distance of the actual target.
  269.  *  focalLength    - Focal Length (same as in CalcHyperfocalDist()).
  270.  */
  271. static double CalcNearEdge(double hyperfocalDist,
  272.                double distOfTarget,
  273.                double focalLength) {
  274.   return ((hyperfocalDist * distOfTarget) / (hyperfocalDist +
  275.                          (distOfTarget - focalLength)));
  276. }
  277.  
  278. /*
  279.  *  Calculates the far edge.
  280.  *
  281.  *  hyperfocalDist - Use the result of CalcHyperfocalDist().
  282.  *  distOfTarget   - Distance of the actual target.
  283.  *  focalLength    - Focal Length (same as in CalcHyperfocalDist()).
  284.  */
  285. static double CalcFarEdge(double hyperfocalDist,
  286.               double distOfTarget,
  287.               double focalLength) {
  288.   return ((hyperfocalDist * distOfTarget) / (hyperfocalDist -
  289.                          (distOfTarget - focalLength)));
  290. }
  291.  
  292. /*
  293.  *  This will cut the decimals. No roundings.
  294.  */
  295.  
  296. double CutDecimals(double d) {
  297.   long l;
  298.  
  299.   l = (long) (d * 1000.0);
  300.   return (double) l / 1000.0;
  301. }
  302.  
  303. /*
  304.  *  Returns pointer to the object by pointer ID from the given form.
  305.  */
  306. static void* GetObjectPtr(FormPtr formP, UInt16 objectID)
  307. {
  308.   FormPtr frmP;
  309.   
  310.   if (formP != NULL) {
  311.     frmP = formP;
  312.   }
  313.   else {
  314.     frmP = FrmGetActiveForm();
  315.   }
  316.   
  317.   return FrmGetObjectPtr(frmP, FrmGetObjectIndex(frmP, objectID));  
  318. }
  319.  
  320. /*
  321.  *  The main form event handler.
  322.  */
  323. static Boolean AppFormHandleEvent(EventPtr event) {
  324.   FormPtr frmP;
  325.   Boolean handled = true;
  326.  
  327.   FieldPtr fieldptr;
  328.   char *textptr;
  329.   char temp[MAXLEN];
  330.   FlpCompDouble value;
  331.   double hyp, focal, aperture, dist, coc;
  332.   char nearstr[MAXLEN];
  333.   char farstr[MAXLEN];
  334.   FlpCompDouble near, far;
  335.  
  336.   MemHandle strFocalLength;
  337.   MemHandle strAperture;
  338.   MemHandle strDistance;
  339.   MemPtr pointer;
  340.  
  341.   frmP = FrmGetActiveForm();
  342.  
  343.  
  344.   /* Keys */
  345.   if (event->eType == keyDownEvent) {
  346.     switch (event->data.keyDown.chr) {
  347.     default:
  348.       handled = false;
  349.       break;
  350.     }
  351.   }
  352.   
  353.   /* Controls */
  354.   else if (event->eType == ctlSelectEvent) {
  355.     switch (event->data.ctlSelect.controlID) {
  356.     case PDoFButton1:
  357.       fieldptr = GetObjectPtr(frmP, PDoFField1);
  358.       textptr = FldGetTextPtr(fieldptr);
  359.       if (textptr != NULL) {
  360.     StrCopy(temp, textptr);
  361.     value.fd = FlpAToF(temp);
  362.     focal = value.d;
  363.       }
  364.       else {
  365.     focal = 0.0;
  366.       }
  367.  
  368.       fieldptr = GetObjectPtr(frmP, PDoFField2);
  369.       textptr = FldGetTextPtr(fieldptr);
  370.       if (textptr != NULL) {
  371.     StrCopy(temp, textptr);
  372.     value.fd = FlpAToF(temp);
  373.     aperture = value.d;
  374.       }
  375.       else {
  376.     aperture = 0.0;
  377.       }
  378.  
  379.       fieldptr = GetObjectPtr(frmP, PDoFField3);
  380.       textptr = FldGetTextPtr(fieldptr);
  381.       if (textptr != NULL) {
  382.     StrCopy(temp, textptr);
  383.     value.fd = FlpAToF(temp);
  384.     dist = value.d * 1000.0;
  385.       }
  386.       else {
  387.     dist = 0.0;
  388.       }
  389.  
  390.       switch (gCoC) {
  391.       case 0:
  392.     coc = 0.033;
  393.     break;
  394.       case 1:
  395.     coc = 0.06;
  396.     break;
  397.       case 2:
  398.     coc = 0.15;
  399.     break;
  400.       default:
  401.     coc = 0.033;
  402.       }
  403.  
  404.       hyp = CalcHyperfocalDist(focal, aperture, coc);
  405.       near.d = CalcNearEdge(hyp, dist, focal) / 1000.0;
  406.       far.d = CalcFarEdge(hyp, dist, focal) / 1000.0;
  407.  
  408.       if (near.d < 0) {
  409.     StrCopy(nearstr, "[inf]");
  410.       }
  411.       else {
  412.     printDouble(CutDecimals(near.d), nearstr);
  413.       }
  414.       if (far.d < 0) {
  415.     StrCopy(farstr, "[inf]");
  416.       }
  417.       else {
  418.     printDouble(CutDecimals(far.d), farstr);
  419.       }
  420.  
  421.       gFocalLength = focal;
  422.       gAperture = aperture;
  423.       gDistance = dist / 1000.0;
  424.  
  425.       FrmCustomAlert(InformationResults, nearstr, farstr, " ");
  426.       
  427.       handled = true;
  428.       break;
  429.     default:
  430.       handled = false;
  431.       break;
  432.     }
  433.   }
  434.   
  435.   /* Menus */
  436.   else if (event->eType == menuEvent) {
  437.     switch (event->data.menu.itemID) {
  438.     default:
  439.       handled = false;
  440.       break;
  441.     }
  442.   }
  443.   
  444.   /* Popup lists */
  445.   else if (event->eType == popSelectEvent) {
  446.     switch (event->data.popSelect.listID) {
  447.     case PDoFList1:
  448.       gCoC = event->data.popSelect.selection;
  449.       handled = false;
  450.       break;
  451.     default:
  452.       handled = false;
  453.       break;
  454.     }
  455.   }
  456.   
  457.   /* Form open */
  458.   else if (event->eType == frmOpenEvent) {
  459.     FrmDrawForm(frmP);
  460.  
  461.     strFocalLength = MemHandleNew(MAXLEN);
  462.     strAperture = MemHandleNew(MAXLEN);
  463.     strDistance = MemHandleNew(MAXLEN);
  464.  
  465.     value.d = CutDecimals(gFocalLength);
  466.     printDouble(value.d, temp);
  467.     pointer = MemHandleLock(strFocalLength);
  468.     StrCopy(pointer, temp);
  469.     MemHandleUnlock(strFocalLength);
  470.     fieldptr = GetObjectPtr(frmP, PDoFField1);
  471.     FldSetText(fieldptr, strFocalLength, 0, MAXLEN);
  472.     FldDrawField(fieldptr);
  473.  
  474.     value.d = CutDecimals(gAperture);
  475.     printDouble(value.d, temp);
  476.     pointer = MemHandleLock(strAperture);
  477.     StrCopy(pointer, temp);
  478.     MemHandleUnlock(strAperture);
  479.     fieldptr = GetObjectPtr(frmP, PDoFField2);
  480.     FldSetText(fieldptr, strAperture, 0, MAXLEN);
  481.     FldDrawField(fieldptr);
  482.  
  483.     value.d = CutDecimals(gDistance);
  484.     printDouble(value.d, temp);
  485.     pointer = MemHandleLock(strDistance);
  486.     StrCopy(pointer, temp);
  487.     MemHandleUnlock(strDistance);
  488.     fieldptr = GetObjectPtr(frmP, PDoFField3);
  489.     FldSetText(fieldptr, strDistance, 0, MAXLEN);
  490.     FldDrawField(fieldptr);
  491.  
  492.     LstSetSelection(GetObjectPtr(frmP, PDoFList1), gCoC);
  493.     CtlSetLabel(GetObjectPtr(frmP, PDoFTrigger1),
  494.         LstGetSelectionText(GetObjectPtr(frmP, PDoFList1), gCoC));
  495.   }
  496.  
  497.   /* Form close */
  498.   else if (event->eType == frmCloseEvent) {
  499.     handled = false;
  500.   }
  501.   else {
  502.     handled = false;
  503.   }
  504.   
  505.   return handled;
  506. }
  507.  
  508. /*
  509.  *  Application event handler.
  510.  */
  511. static Boolean AppHandleEvent(EventPtr event) {
  512.   Boolean eventHandled = true;
  513.   FormPtr frm;
  514.   
  515.   if (event->eType == frmLoadEvent) {
  516.     frm = FrmInitForm(event->data.frmLoad.formID);
  517.     FrmSetActiveForm(frm);
  518.     
  519.     switch (event->data.frmLoad.formID) {
  520.     case PDoFForm:
  521.       FrmSetEventHandler(frm, AppFormHandleEvent);
  522.       break;
  523.     default:
  524.       eventHandled = false;
  525.       break;
  526.     }
  527.   }
  528.   else {
  529.     eventHandled = false;
  530.   }
  531.   
  532.   return eventHandled;
  533. }
  534.  
  535. /*
  536.  *  Application event loop.
  537.  */
  538. static void AppEventLoop() {
  539.   UInt16 error;
  540.   EventType event;
  541.   
  542.   do {
  543.     EvtGetEvent(&event, evtWaitForever);
  544.     if (!SysHandleEvent(&event)) {
  545.       if (!MenuHandleEvent(NULL, &event, &error)) {
  546.         if (!AppHandleEvent(&event)) {
  547.           FrmDispatchEvent(&event);
  548.         }
  549.       }
  550.     }
  551.   } while (event.eType != appStopEvent);
  552. }
  553.  
  554. /*
  555.  *  Start-up function.
  556.  */
  557. static UInt16 StartApplication() {
  558.   UInt16 size;
  559.  
  560.   size = sizeof(double);
  561.   PrefGetAppPreferences(CreatorID, 0, &gFocalLength, &size, true);
  562.   PrefGetAppPreferences(CreatorID, 1, &gAperture, &size, true);
  563.   PrefGetAppPreferences(CreatorID, 2, &gDistance, &size, true);
  564.   size = sizeof(int);
  565.   PrefGetAppPreferences(CreatorID, 3, &gCoC, &size, true);
  566.  
  567.   return 0;
  568. }
  569.  
  570. /*
  571.  *  Shutdown function.
  572.  */
  573. static void StopApplication() {
  574.   PrefSetAppPreferences(CreatorID, 0, 1, &gFocalLength, sizeof(double), true);
  575.   PrefSetAppPreferences(CreatorID, 1, 1, &gAperture, sizeof(double), true);
  576.   PrefSetAppPreferences(CreatorID, 2, 1, &gDistance, sizeof(double), true);
  577.   PrefSetAppPreferences(CreatorID, 3, 1, &gCoC, sizeof(int), true);
  578.  
  579.   FrmCloseAllForms();
  580. }
  581.  
  582. /*
  583.  *  The main function.
  584.  */
  585. UInt32 PilotMain(UInt16 cmd, MemPtr cmdPBP, UInt16 launchFlags) {
  586.   UInt16 error;
  587.   UInt32 romVersion;
  588.  
  589.   FtrGet(sysFtrCreator, sysFtrNumROMVersion, &romVersion);
  590.  
  591.   if (romVersion < VERSION) {
  592.     return sysErrRomIncompatible;
  593.   }
  594.   
  595.   if (cmd == sysAppLaunchCmdNormalLaunch) {
  596.     error = StartApplication();
  597.     if (error) {
  598.       return error;
  599.     }
  600.     FrmGotoForm(PDoFForm);
  601.     AppEventLoop();
  602.     StopApplication();
  603.   }
  604.   
  605.   return 0;
  606. }
  607.