/*
** PLAYER.C                   Player data
*/



#include "player.h"
#include <string.h>



/*
** InitPlayer(play, slot)     Load a player's initial conditions
*/
void InitPlayer(int play, GRIP_SLOT slot)
  {
  PLAYER* p = &player[play];

  // Save the state information
  p->slot = slot;

  // Slot is not valid
  if (slot == 0)
    {
    // Prepare slot defaults
    strcpy(p->vendor, "Unspecified");
    strcpy(p->product, "controller");
    }

  // Slot is valid
  else
    {
    // Get vendor information
    GrGetVendorName(slot, p->vendor);
    GrGetProductName(slot, p->product);
    }

  // Prepare controller defaults
  p->state = STATE_NORMAL;
  p->left.state = STATE_INVALID;
  p->right.state = STATE_INVALID;
  p->axis.state = STATE_INVALID;

  // Start the position in the center
  p->pos = SLIDER_MIDDLE;

  return;
  }



/*
** UpdatePlayer(play)         Update a player according to the controllers
*/
void UpdatePlayer(int play)
  {
  PLAYER* p = &player[play];
  GRIP_BITFIELD buttons;
  GRIP_VALUE region;

  // Check that the player is active
  if (p->slot == 0)
    return;

  // Check for "hot" unplugging
  if (! (GrGetSlotMap() & (1 << p->slot)) )
    {
    InitPlayer(play, 0);
    return;
    }

  // Read the button states in a lump
  buttons = GrGetPackedValues(p->slot, GRIP_CLASS_BUTTON, 0, 31);
  if (p->left.state == STATE_NORMAL)
    p->left.value = (buttons & p->left.mask) ? 1 : 0;
  if (p->right.state == STATE_NORMAL)
    p->right.value = (buttons & p->right.mask) ? 1 : 0;

  // Update the axis
  if (p->axis.state == STATE_NORMAL)
    {
    // Read the axis value
    p->axis.value = GrGetValue(p->slot, GRIP_CLASS_AXIS, p->axis.index);

    // Update the position on the slider based on the axis position
    // For this demo, the axis is divided up into three equally sized
    // regions, with the middle region being a dead zone.  Depending
    // on the application, it may be preferable to divide the axis
    // differently.
    region = (p->axis.max + 1) / 3;
    if (p->axis.value < region)
      p->pos = (p->pos <= SLIDER_MIN) ? SLIDER_MIN : p->pos-1;
    else if (p->axis.value > p->axis.max - region)
      p->pos = (p->pos >= SLIDER_MAX) ? SLIDER_MAX : p->pos+1;
    }

  return;
  }



PLAYER player[2];

