Pre Release Testing:
====================

* check the version number

VERSION="0.1.0"
TAG="v${VERSION}"
git tag -s  "${TAG}" -m "jstest-gtk ${TAG}" 
git archive --format=tar --prefix="jstest-gtk-${VERSION}/" ${TAG} | bzip2 -c > /tmp/jstest-gtk-${VERSION}.tar.bz2
git push --tags

==========
[[ TODO ]]
==========

* [CLEANUP] center font in ButtonWidget (current way is a dirty hack)

* [FEATURE] axis names (ABS_X, ...) should be used instead of raw axis numbers
  to guess which layout is correct, also the layout should be properly
  labeled

* [BUG] add some more checks to catch invalid button/axis mappings supplied
  to the joydev interface

* [BUG] swapping axis must also swap calibration data

* [FEATURE] provide additional support for SDL and evdev devices


=================================
[[ Possible Future Improvments ]]
=================================

* draw calibration icon

* draw mapping icon

* Joystick name of a joydev is taken from USB and build up of
  (iManufacturer + iProduct), but thats ugly, (idVendor + idProduct)
  or just idProduct would give much prettier name:

  idVendor           0x045e Microsoft Corp.
  idProduct          0x0007 SideWinder Game Pad
  bcdDevice            1.05
  iManufacturer           1 Microsoft<AE>
  iProduct                2 Microsoft<AE> SideWinder<AE> Game Pad USB

* the joystick name seems to be the only way to link from a joydev to
  a evdev, hack some code together to accomplish that as it would
  allow proper reset of calibration data

* axis names very buggy:
  - ABS_RZ instead of ABS_RUDDER (Sidewinder2)
  - ABS_RZ,ABS_THROTTLE instead of ABS_RX,ABS_RY (Thrustmaster gamepad)
  - BTN_TL2,BTN_TR2 instead of BTN_START, BTN_MODE (Sidewinder gamepad)
  - ...

* create a small database with most common joysticks, maybe add a way
  how a user can automatically submit his joystick profile, to ease
  the database generation

==================
[[ Random Notes ]]
==================

* jscal:

# Remove any calibration and report raw USB data
jsscal -s 6,0,0,0,0,0,0,0,0,0,0,0,0 /dev/input/js0 

jscal -s
6, // number of axes

.--- type (0: raw, 1: "broken line")
|  .--- prec (seems to be read only, taken for evdev's absfuzz)
|  |    .---.- coef[0], coef[1], ...
v  v    v   v
1, 0, -15,  15, 5534751,   5534751, ???
1, 0, -15,  15, 5534751,   5534751,
1, 0, -15,  15, 5534751,   5534751,
1, 0, 112, 142, 5534751,   5534751,
1, 0,   0,   0, 536870912, 536870912, (1<<29)
1, 0,   0,   0, 536870912, 536870912

type == 0 -> none of coef used
type == 1 -> coef[0:4] used

type == 0 -> "none (raw)"
type == 1 -> "broken line"

# Original
jscal -s 6,1,0,-15,15,5534751,5534751,1,0,-15,15,5534751,5534751,1,0,-15,15,5534751,5534751,1,0,112,142,5534751,5534751,1,0,0,0,536870912,536870912,1,0,0,0,536870912,536870912 /dev/input/js0

# No Dead
jscal -s 6,1,0,0,0,5534751,5534751,1,0,0,0,5534751,5534751,1,0,0,0,5534751,5534751,1,0,112,142,5534751,5534751,1,0,0,0,536870912,536870912,1,0,0,0,536870912,536870912 /dev/input/js0


int solve_broken(int *results /* coef[4] */, struct correction_data inputs)
{
  results[0] = inputs.cmin[CENTER];
  results[1] = inputs.cmax[CENTER];
  results[2] = (32767.0 / (inputs.cmin[CENTER]  - inputs.cmax[MINIMUM])) * 16384.0;
  results[3] = (32767.0 / (inputs.cmin[MAXIMUM] - inputs.cmax[CENTER]))  * 16384.0;

  results[2] = (32767 * 16384) / left_range
  results[3] = (32767 * 16384) / left_range

  // in float terms:
  // [2] = 1.0f / left_range;
  // [3] = 1.0f / right_range;

  return 1;
}

Apply coef:
===========

  if (value > corr->coef[0])
    { 
      if (value < corr->coef[1])
        {
          value = 0;
        }
      else
        {
          value = (corr->coef[3] * (value - corr->coef[1])) / 16384; 
        }
    }
  else
    {
      value = (corr->coef[2] * (value - corr->coef[0])) / 16384;
    }

  return value < -32767 ? -32767 : (value > 32767 ? 32767 : value);

Set coef:
=========

  joydev->corr[i].type = JS_CORR_BROKEN;
  joydev->corr[i].prec = dev->absfuzz[j];
  joydev->corr[i].coef[0] = (dev->absmax[j] + dev->absmin[j]) / 2 - dev->absflat[j];
  joydev->corr[i].coef[1] = (dev->absmax[j] + dev->absmin[j]) / 2 + dev->absflat[j];

  t = (dev->absmax[j] - dev->absmin[j]) / 2 - 2 * dev->absflat[j];
  if (t)
    {
      joydev->corr[i].coef[2] = (1 << 29) / t;
      joydev->corr[i].coef[3] = (1 << 29) / t;
    }

# EOF #
