Logo Search packages:      
Sourcecode: libjsw version File versions

calibrationfio.c

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>

#include "../include/cfgfmt.h"
#include "../include/string.h"
#include "../include/strexp.h"
#include "../include/disk.h"
#include "../include/fio.h"

#include "../include/jsw.h"


void JSResetAllAxisTolorance(js_data_struct *jsd);
int JSLoadCalibrationUNIX(js_data_struct *jsd);
char **JSLoadDeviceNamesUNIX(
      int *total, const char *calibration
);


#define MAX(a,b)        (((a) > (b)) ? (a) : (b))
#define MIN(a,b)        (((a) < (b)) ? (a) : (b))
#define CLIP(a,l,h)     (MIN(MAX((a),(l)),(h)))


/*
 *      Loads the calibration data from the calibration file specifeid
 *      on the given jsd structure. First an entry for the device
 *      specified by the jsd structure is looked for in the calibration
 *      file if (and only if) it is found then the axis and button
 *      values for that device will be loaded.
 *
 *      Additional axises and buttons may be allocated on the given
 *      jsd structure by this function if they are found to be defined
 *      for the device in question in the calibration file.
 */
int JSLoadCalibrationUNIX(js_data_struct *jsd)
{
      char is_this_device = 0;
      const char *cstrptr, *this_device_name;
        char *line_buf;
  
        FILE *fp;
  
        char parm[CFG_PARAMETER_MAX];
        char val[CFG_VALUE_MAX];
        int lines_read = 0;

      int axis_num, button_num;
      js_axis_struct *axis_ptr;
      js_button_struct *button_ptr;


      if(jsd == NULL)
          return(-1);

      /* Device name must be specified. */
      this_device_name = (const char *)jsd->device_name;
      if(this_device_name == NULL)
          return(-1);

      /* Calibration file must be specified. */
        if(jsd->calibration_file == NULL)
            return(-1);

      /* Open calibration file. */
        fp = FOpen(jsd->calibration_file, "rb");
        if(fp == NULL)
          return(-1);

/* Reads the next line from fp, first free()ing line_buf and then
 * allocating the new line to line_buf. Then uses cstrptr to parse the
 * parameter and value, the parsed values will be placed in the variables
 * parm and val. The value of lines_read will also be incremented.
 */
#define DO_GET_LINE     \
{ \
 /* Read next non-comment line. */ \
 free(line_buf); \
 line_buf = FReadNextLineAllocCount( \
  fp, UNIXCFG_COMMENT_CHAR, &lines_read \
 ); \
 if(line_buf == NULL) \
  break; \
 \
 /* Fetch parameter. */ \
 cstrptr = StringCfgParseParm(line_buf); \
 if(cstrptr == NULL) \
  continue; \
 strncpy(parm, cstrptr, CFG_PARAMETER_MAX); \
 parm[CFG_PARAMETER_MAX - 1] = '\0'; \
 \
 /* Fetch value. */ \
 cstrptr = StringCfgParseValue(line_buf); \
 if(cstrptr == NULL) \
  cstrptr = "0"; \
 strncpy(val, cstrptr, CFG_VALUE_MAX); \
 val[CFG_VALUE_MAX - 1] = '\0'; \
}

      /* Begin reading calibration file. */
      line_buf = NULL;
        while(1)
        {
          DO_GET_LINE

            /* Start of joystick device block? */
            if(!strcasecmp(parm, "BeginJoystick"))
            {
            /* Joystick device name must match the value for
             * the BeginJoystick parameter, this is so that we
             * know that this is a configuration block for
             * this device (jsd->device_name).
             */
            if(strcmp(val, this_device_name))
                is_this_device = 0;
            else
                is_this_device = 1;

            /* Enter loop to read and handle each line for this
             * configuration block.
             */
                while(1)
                {
                DO_GET_LINE

                    /* Start of axis block? */
                    if(!strcasecmp(parm, "BeginAxis") &&
                       is_this_device
                    )
                    {
                        /* Get axis number and check if it matches one on the
                         * jsd structure.
                         */
                        axis_num = atoi(val);
                        if(JSIsAxisAllocated(jsd, axis_num))
                        {
                            axis_ptr = jsd->axis[axis_num];
                        }
                        else if((axis_num >= jsd->total_axises) &&
                                (axis_num >= 0)
                        )
                        {
                            /* Need to allocate more axises. */
                            int i, p = jsd->total_axises;
                            jsd->total_axises = axis_num + 1;
                            jsd->axis = (js_axis_struct **)realloc(
                                jsd->axis,
                                jsd->total_axises * sizeof(js_axis_struct *)
                            );
                            if(jsd->axis == NULL)
                            {
                                jsd->total_axises = 0;
                                axis_ptr = NULL;
                                axis_num = -1;
                            }
                            else
                            {
                                for(i = p; i < jsd->total_axises; i++)
                                    jsd->axis[i] = NULL;
                                jsd->axis[axis_num] = axis_ptr = (js_axis_struct *)calloc(
                                    1, sizeof(js_axis_struct)
                                );
                            }
                        }
                        else
                        {
                            axis_ptr = NULL;
                            axis_num = -1;
                        }

                        /* Enter loop to read and handle each line for
                   * this configuration block.
                   */
                        while(1)
                        {
                      DO_GET_LINE

                      /* Minimum */
                      if(!strcasecmp(parm, "Minimum"))
                      {
                        if(axis_ptr != NULL)
                            axis_ptr->min = atoi(val);
                      }
                            /* Maximum */
                            else if(!strcasecmp(parm, "Maximum"))
                            {
                                if(axis_ptr != NULL)
                                    axis_ptr->max = atoi(val);
                            }
                            /* Center */
                            else if(!strcasecmp(parm, "Center"))
                            {
                                if(axis_ptr != NULL)
                                    axis_ptr->cen = atoi(val);
                            }
                            /* NullZone */
                            else if(!strcasecmp(parm, "NullZone"))
                            {
                                if(axis_ptr != NULL)
                                    axis_ptr->nz = MAX(atoi(val), 0);
                            }
                            /* Tolorance */
                            else if(!strcasecmp(parm, "Tolorance"))
                            {
                                if(axis_ptr != NULL)
                        {
                                    axis_ptr->tolorance = MAX(atoi(val), 0);
                            axis_ptr->flags |= JSAxisFlagTolorance;
                        }
                            }
                            /* Flip */
                            else if(!strcasecmp(parm, "Flip") ||
                                    !strcasecmp(parm, "Flipped")
                      )
                            {
                                if(axis_ptr != NULL)
                                    axis_ptr->flags |= JSAxisFlagFlipped;
                            }
                            /* IsHat */
                            else if(!strcasecmp(parm, "IsHat"))
                            {
                                if(axis_ptr != NULL)
                                    axis_ptr->flags |= JSAxisFlagIsHat;
                            }

                            /* New correctional parameters, for versions 1.5.0 and
                             * up.
                             */
                            /* Correction level. */
                            else if(!strcasecmp(parm, "CorrectionLevel"))
                            {
                                if(axis_ptr != NULL)
                                    axis_ptr->correction_level = MAX(atoi(val), 0);
                            }
                            /* Dead zone minimum. */
                            else if(!strcasecmp(parm, "DeadZoneMinimum") ||
                                    !strcasecmp(parm, "DeadZoneMin") ||
                                    !strcasecmp(parm, "DZMin")
                            )
                            {
                                if(axis_ptr != NULL)
                                    axis_ptr->dz_min = atoi(val);
                            }
                            /* Dead zone maximum. */
                            else if(!strcasecmp(parm, "DeadZoneMaximum") ||
                                    !strcasecmp(parm, "DeadZoneMax") ||
                                    !strcasecmp(parm, "DZMax")
                            )
                            {
                                if(axis_ptr != NULL)
                                    axis_ptr->dz_max = atoi(val);
                            }
                            /* Correctional coefficient min 1st degree. */
                            else if(!strcasecmp(parm, "CorrectionalCoefficientMinimum1") ||
                                    !strcasecmp(parm, "CorrCoeffMin1")
                            )
                            {
                                if(axis_ptr != NULL)
                                    axis_ptr->corr_coeff_min1 = CLIP(atof(val), 0.0, 1.0);
                            }
                            /* Correctional coefficient max 1st degree. */
                            else if(!strcasecmp(parm, "CorrectionalCoefficientMaximum1") ||
                                    !strcasecmp(parm, "CorrCoeffMax1")
                            )
                            {
                                if(axis_ptr != NULL)
                                    axis_ptr->corr_coeff_max1 = CLIP(atof(val), 0.0, 1.0);
                            }
                            /* Correctional coefficient min 2nd degree. */
                            else if(!strcasecmp(parm, "CorrectionCoefficientMinimum2") ||
                                    !strcasecmp(parm, "CorrCoeffMin2")
                            )
                            {
                                if(axis_ptr != NULL)
                                    axis_ptr->corr_coeff_min2 = CLIP(atof(val), 0.0, 1.0);
                            }
                            /* Correctional coefficient max 2nd degree. */
                            else if(!strcasecmp(parm, "CorrectionCoefficientMaximum2") ||
                                    !strcasecmp(parm, "CorrCoeffMax2")
                            )
                            {
                                if(axis_ptr != NULL)
                                    axis_ptr->corr_coeff_max2 = CLIP(atof(val), 0.0, 1.0);
                            }

                            /* EndAxis */
                            else if(!strcasecmp(parm, "EndAxis"))
                            {
                        axis_ptr = NULL;
                        axis_num = -1;
                                break;
                            }
                  }     /* Read axis block loop. */
                    }
                    /* Start of button block? */
                    else if(!strcasecmp(parm, "BeginButton") &&
                            is_this_device
                    )
                    {
                        /* Get button number and check if it matches one on the
                         * jsd structure.
                         */
                        button_num = atoi(val);
                        if(JSIsButtonAllocated(jsd, button_num))
                        {
                            button_ptr = jsd->button[button_num];
                        }
                        else if((button_num >= jsd->total_buttons) &&
                                (button_num >= 0)
                        )
                        {
                            /* Need to allocate more buttons. */
                            int i, p = jsd->total_buttons;
                            jsd->total_buttons = button_num + 1;
                            jsd->button = (js_button_struct **)realloc(
                                jsd->button,
                                jsd->total_buttons * sizeof(js_button_struct *)
                            );
                            if(jsd->button == NULL)
                            {
                                jsd->total_buttons = 0;
                                button_ptr = NULL;
                                button_num = -1;
                            }
                            else
                            {
                                for(i = p; i < jsd->total_buttons; i++)
                                    jsd->button[i] = NULL;
                                jsd->button[button_num] = button_ptr = (js_button_struct *)calloc(
                                    1, sizeof(js_button_struct)
                                );
                            }
                        }
                        else
                        {
                            button_ptr = NULL;
                            button_num = -1;
                        }

                        /* Enter loop to read and handle each line for
                         * this configuration block.
                         */
                        while(1)
                        {
                      DO_GET_LINE

                            /* EndButton */
                            if(!strcasecmp(parm, "EndButton"))
                            {
                        button_ptr = NULL;
                        button_num = -1;
                                break;
                            }
                  }     /* Read button block loop. */
                    }
                /* Name of joystick device? */
                else if(!strcasecmp(parm, "Name") &&
                      is_this_device
                )
                    {
                  free(jsd->name);
                  jsd->name = strdup(val);
                    }
                    /* Last time calibrated? */
                    else if(!strcasecmp(parm, "LastCalibrated") &&
                            is_this_device
                    )
                    {
                        jsd->last_calibrated = MAX(atol(val), 0);
                    }
                    /* End of current joystick device block? */
                    else if(!strcasecmp(parm, "EndJoystick"))
                    {
                  is_this_device = 0;
                  break;
                    }
                /* Other parameter? */
                else
                {
                  /* Other parameter, ignore. */
                }
            }     /* Read device block loop. */
          }
          /* Other parameter? */
          else
          {
            /* Other parameter, ignore. */
          }
      }     /* Begin reading file. */

      /* Deallocate line buffer just in case. */
      free(line_buf);
      line_buf = NULL;

      /* Close calibration file. */
      FClose(fp);
      fp = NULL;

#undef DO_GET_LINE

      return(0);
}

/*
 *    Gets a list of calibrated devices found in the specified
 *    calibration file.
 *
 *    The returned list of strings and the pointer array must be
 *    deallocated by the calling function.
 */
char **JSLoadDeviceNamesUNIX(
      int *total, const char *calibration
)
{
        FILE *fp;
        int n, lines_read = 0;
      const char *cstrptr;
        char *line_buf;
        char parm[CFG_PARAMETER_MAX];
        char val[CFG_VALUE_MAX];

        int strc = 0;
        char **strv = NULL;


      if(total != NULL)
          *total = 0;

      /* Given calibration file exists? */
        if(calibration == NULL) 
            return(strv);   

      /* Open calibration file. */
        fp = FOpen(calibration, "rb");
        if(fp == NULL)
            return(strv);

/* Reads the next line from fp, first free()ing line_buf and then
 * allocating the new line to line_buf. Then uses cstrptr to parse the
 * parameter and value, the parsed values will be placed in the variables
 * parm and val. The value of lines_read will also be incremented.
 */
#define DO_GET_LINE     \
{ \
 /* Read next non-comment line. */ \
 free(line_buf); \
 line_buf = FReadNextLineAllocCount( \
  fp, UNIXCFG_COMMENT_CHAR, &lines_read \
 ); \
 if(line_buf == NULL) \
  break; \
 \
 /* Fetch parameter. */ \
 cstrptr = StringCfgParseParm(line_buf); \
 if(cstrptr == NULL) \
  continue; \
 strncpy(parm, cstrptr, CFG_PARAMETER_MAX); \
 parm[CFG_PARAMETER_MAX - 1] = '\0'; \
 \
 /* Fetch value. */ \
 cstrptr = StringCfgParseValue(line_buf); \
 if(cstrptr == NULL) \
  cstrptr = "0"; \
 strncpy(val, cstrptr, CFG_VALUE_MAX); \
 val[CFG_VALUE_MAX - 1] = '\0'; \
}

        /* Begin reading calibration file. */
        line_buf = NULL;
        while(1)
        {
          DO_GET_LINE

            /* Start of joystick device block? */
            if(!strcasecmp(parm, "BeginJoystick"))
            {
                n = strc;
                strc = n + 1;
                strv = (char **)realloc(
                    strv,
                    strc * sizeof(char *)
                );
                if(strv == NULL)
                {
                    strc = 0;
                    continue;
                }

                strv[n] = strdup(val);

                /* Enter loop to read and handle each line for this
                 * configuration block.
                 */
                while(1)
                {
                    DO_GET_LINE

                    /* End of current joystick device block? */
                    if(!strcasecmp(parm, "EndJoystick"))
                    {
                        break;
                    }
                }       /* Read device block loop. */
            }
        }   /* Begin reading calibration file. */

        /* Deallocate line buffer just in case. */
        free(line_buf);
        line_buf = NULL;

      /* Close calibration file. */
      FClose(fp);
      fp = NULL;

#undef DO_GET_LINE

        /* Update total strings returned. */
        if(total != NULL)
            *total = strc;

      return(strv);
}

Generated by  Doxygen 1.6.0   Back to index