static void wpad_update()

in cores/genesis/gx/gx_input.c [713:1119]


static void wpad_update(s8 chan, u8 i, u32 exp)
{
  /* WPAD data */
  WPADData *data = WPAD_Data(chan);

  /* WPAD status */
  u32 p = data->btns_h;

  /* Analog sticks */
  s8 x = 0;
  s8 y = 0;

  if (exp != WPAD_EXP_NONE)
  {
    x = wpad_StickX(data,0);
    y = wpad_StickY(data,0);
  }

  /* Retrieve current key mapping */
  u32 *wpad_keymap = config.wpad_keymap[exp + (chan * 3)];

  /* Emulated device */
  switch (input.dev[i])
  {
    case DEVICE_PAD6B:
    {
      /* X,Y,Z,MODE buttons */
      if (p & wpad_keymap[KEY_BUTTONX]) input.pad[i] |= INPUT_X;
      if (p & wpad_keymap[KEY_BUTTONY]) input.pad[i] |= INPUT_Y;
      if (p & wpad_keymap[KEY_BUTTONZ]) input.pad[i] |= INPUT_Z;
      if (p & wpad_keymap[KEY_MODE])    input.pad[i] |= INPUT_MODE;
    }

    case DEVICE_PAD3B:
    {
      /* A button */
      if (p & wpad_keymap[KEY_BUTTONA]) input.pad[i] |= INPUT_A;
    }

    case DEVICE_PAD2B:
    {
      /* D-PAD */
      if ((p & wpad_dirmap[exp][PAD_UP]) || (y > ANALOG_SENSITIVITY)) input.pad[i] |= INPUT_UP;
      else if ((p & wpad_dirmap[exp][PAD_DOWN]) || (y < -ANALOG_SENSITIVITY)) input.pad[i] |= INPUT_DOWN;
      if ((p & wpad_dirmap[exp][PAD_LEFT]) || (x < -ANALOG_SENSITIVITY)) input.pad[i] |= INPUT_LEFT;
      else if ((p & wpad_dirmap[exp][PAD_RIGHT]) || (x > ANALOG_SENSITIVITY)) input.pad[i] |= INPUT_RIGHT;

      /* default buttons */
      if (p & wpad_keymap[KEY_BUTTONB]) input.pad[i] |= INPUT_B;
      if (p & wpad_keymap[KEY_BUTTONC]) input.pad[i] |= INPUT_C;
      if (p & wpad_keymap[KEY_START])   input.pad[i] |= INPUT_START;

      break;
    }

    case DEVICE_XE_1AP:
    {
      /* Left Stick analog position [0-255] */
      input.analog[i][0] = (x + 128);
      input.analog[i][1] = y ? (127 - y) : 128;

      /* Right Stick analog position [0-255] */
      if (exp == WPAD_EXP_CLASSIC)
      {
        /* Classic Controller right stick */
        x = wpad_StickX(data,1);
        y = wpad_StickY(data,1);

        /* Emulated stick is unidirectional but can be rotated */
        if (abs(x) > abs(y))
        {
         input.analog[i+1][0] = (x + 128);
        }
        else 
        {
         input.analog[i+1][0] = (y + 128);
        }
      }
      else
      {
        /* Wiimote D-PAD */
        if ((p & wpad_dirmap[exp][PAD_DOWN]) || (p & wpad_dirmap[exp][PAD_LEFT])) input.analog[i+1][0]-=2;
        else if ((p & wpad_dirmap[exp][PAD_UP]) || (p & wpad_dirmap[exp][PAD_RIGHT])) input.analog[i+1][0]+=2;
 
        /* Limits */
        if (input.analog[i+1][0] < 0) input.analog[i+1][0] = 0;
        else if (input.analog[i+1][0] > 255) input.analog[i+1][0] = 255;
      }

      /* Buttons */
      if (p & wpad_keymap[KEY_BUTTONA]) input.pad[i] |= INPUT_XE_A;
      if (p & wpad_keymap[KEY_BUTTONB]) input.pad[i] |= INPUT_XE_B;
      if (p & wpad_keymap[KEY_BUTTONC]) input.pad[i] |= INPUT_XE_C;
      if (p & wpad_keymap[KEY_START])   input.pad[i] |= INPUT_XE_START;
      if (p & wpad_keymap[KEY_BUTTONX]) input.pad[i] |= INPUT_XE_D;
      if (p & wpad_keymap[KEY_BUTTONY]) input.pad[i] |= INPUT_XE_E1;
      if (p & wpad_keymap[KEY_BUTTONZ]) input.pad[i] |= INPUT_XE_E2;
      if (p & wpad_keymap[KEY_MODE])    input.pad[i] |= INPUT_XE_SELECT;

      break;
    }

    case DEVICE_SPORTSPAD:
    {
      /* X analog position [0-255] */
      if (p & wpad_dirmap[exp][PAD_LEFT]) input.analog[i][0]-=2;
      else if (p & wpad_dirmap[exp][PAD_RIGHT]) input.analog[i][0]+=2;
      else input.analog[i][0] = (x + 128);

      /* Y analog position [0-255] */
      if (p & wpad_dirmap[exp][PAD_UP]) input.analog[i][1]-=2;
      else if (p & wpad_dirmap[exp][PAD_DOWN]) input.analog[i][1]+=2;
      else input.analog[i][1] = y ? (127 - y) : (128 - y);

      /* Limits */
      if (input.analog[i][0] < 0) input.analog[i][0] = 0;
      else if (input.analog[i][0] > 255) input.analog[i][0] = 255;
      if (input.analog[i][1] < 0) input.analog[i][1] = 0;
      else if (input.analog[i][1] > 255) input.analog[i][1] = 255;

      /* Buttons */
      if (p & wpad_keymap[KEY_BUTTONB]) input.pad[i] |= INPUT_BUTTON1;
      if (p & wpad_keymap[KEY_BUTTONC]) input.pad[i] |= INPUT_BUTTON2;
      if (p & wpad_keymap[KEY_START])   input.pad[i] |= INPUT_START;

      break;
    }

    case DEVICE_PADDLE:
    {
      /* X analog position [0-255] */
      if (exp == WPAD_EXP_NONE)
      {
        /* Wiimote D-PAD */
        if (p & wpad_dirmap[exp][PAD_LEFT]) input.analog[i][0]-=2;
        else if (p & wpad_dirmap[exp][PAD_RIGHT]) input.analog[i][0]+=2;

        /* Limits */
        if (input.analog[i][0] < 0) input.analog[i][0] = 0;
        else if (input.analog[i][0] > 255) input.analog[i][0] = 255;
      }
      else
      {
        /* Left analog stick */
        input.analog[i][0] = (x + 128);
      }

      /* Buttons */
      if (p & wpad_keymap[KEY_BUTTONB]) input.pad[i] |= INPUT_BUTTON1;
      if (p & wpad_keymap[KEY_START])   input.pad[i] |= INPUT_START;

      break;
    }

    case DEVICE_LIGHTGUN:
    {
      /* Gun screen position (x,y) */
      if (exp != WPAD_EXP_CLASSIC)
      {
        /* Wiimote IR */
        struct ir_t ir;
        WPAD_IR(chan, &ir);

        if (ir.valid)
        {
          /* screen position */
          input.analog[i][0] = ((ir.x + config.calx) * bitmap.viewport.w) / 640;
          input.analog[i][1] = ((ir.y + config.caly) * bitmap.viewport.h) / 480;
        }
        else
        {
          /* lightgun should point outside screen area */
          input.analog[i][0] = 512;
          input.analog[i][1] = 512;
        }
      }
      else
      {
        /* Classic Controller analog stick */
        input.analog[i][0] += x / ANALOG_SENSITIVITY;
        input.analog[i][1] -= y / ANALOG_SENSITIVITY;

        /* Limits */
        if (input.analog[i][0] < 0) input.analog[i][0] = 0;
        else if (input.analog[i][0] > bitmap.viewport.w) input.analog[i][0] = bitmap.viewport.w;
        if (input.analog[i][1] < 0) input.analog[i][1] = 0;
        else if (input.analog[i][1] > bitmap.viewport.h) input.analog[i][1] = bitmap.viewport.h;
      }

      /* Buttons */
      if (p & wpad_keymap[KEY_BUTTONA]) input.pad[i] |= INPUT_A;
      if (p & wpad_keymap[KEY_BUTTONB]) input.pad[i] |= INPUT_B;
      if (p & wpad_keymap[KEY_BUTTONC]) input.pad[i] |= INPUT_C;
      if (p & wpad_keymap[KEY_START])   input.pad[i] |= INPUT_START;

      break;
    }

    case DEVICE_MOUSE:
    {
      /* Mouse relative movement (-255,255) */
      if (MOUSE_IsConnected())
      {
        /* USB mouse support */
        mouse_event event;
        MOUSE_GetEvent(&event);
        MOUSE_FlushEvents();

        /* USB mouse position (-127;+127) -> (-255;+255) */
        input.analog[i][0] = event.rx * 2;
        input.analog[i][1] = event.ry * 2;

        /* USB mouse buttons */
        if (event.button & 1) input.pad[i] |= INPUT_MOUSE_RIGHT;
        if (event.button & 2) input.pad[i] |= INPUT_MOUSE_CENTER;
        if (event.button & 4) input.pad[i] |= INPUT_MOUSE_LEFT;
      }
      else if (exp != WPAD_EXP_CLASSIC)
      {
        /* Wiimote IR (buggy) */
        struct ir_t ir;
        WPAD_IR(chan, &ir);

        /* Only if Wiimote is pointed to screen */
        if(ir.smooth_valid)
        {
          input.analog[i][0] = (int)((ir.sx - 512) / 2 / ANALOG_SENSITIVITY);
          input.analog[i][1] = (int)((ir.sy - 384) * 2 / 3 / ANALOG_SENSITIVITY);
        }
      }
      else
      {
        /* Classic Controller analog stick position (-127;+127) -> (-255;+255) */
        input.analog[i][0] = (x / ANALOG_SENSITIVITY) * 2;
        input.analog[i][1] = (y / ANALOG_SENSITIVITY) * 2;
      }

      /* Y-Axis inversion */
      if (config.invert_mouse)
      {
        input.analog[i][1] = -input.analog[i][1];
      }

      /* Buttons */
      if (p & wpad_keymap[KEY_BUTTONA]) input.pad[i] |= INPUT_MOUSE_CENTER;
      if (p & wpad_keymap[KEY_BUTTONB]) input.pad[i] |= INPUT_MOUSE_LEFT;
      if (p & wpad_keymap[KEY_BUTTONC]) input.pad[i] |= INPUT_MOUSE_RIGHT;
      if (p & wpad_keymap[KEY_START])   input.pad[i] |= INPUT_START;

      break;
    }

    case DEVICE_PICO:
    {
      /* D-PAD */
      if (p & PAD_BUTTON_UP) input.pad[i] |= INPUT_UP;
      else if (p & PAD_BUTTON_DOWN) input.pad[i] |= INPUT_DOWN;
      if (p & PAD_BUTTON_LEFT) input.pad[i] |= INPUT_LEFT;
      else if (p & PAD_BUTTON_RIGHT) input.pad[i] |= INPUT_RIGHT;

      /* PEN screen position (x,y) */
      if (exp != WPAD_EXP_CLASSIC)
      {
        /* Wiimote IR */
        struct ir_t ir;
        WPAD_IR(chan, &ir);
        if (ir.valid)
        {
          input.analog[0][0] = 0x3c  + ((ir.x + config.calx) * (0x17c - 0x3c  + 1)) / 640;
          input.analog[0][1] = 0x1fc + ((ir.y + config.caly) * (0x2f7 - 0x1fc + 1)) / 480;
        }
      }
      else
      {
        /* Classic Controller analog stick */
        input.analog[0][0] += x / ANALOG_SENSITIVITY;
        input.analog[0][1] -= y / ANALOG_SENSITIVITY;

        /* Limits */
        if (input.analog[0][0] > 0x17c) input.analog[0][0] = 0x17c;
        else if (input.analog[0][0] < 0x3c) input.analog[0][0] = 0x3c;
        if (input.analog[0][1] < 0x1fc) input.analog[0][1] = 0x1fc;
        else if (input.analog[0][1] > 0x2f7) input.analog[0][1] = 0x2f7;
      }

      /* PEN & RED buttons */
      if (p & wpad_keymap[KEY_BUTTONA]) input.pad[0] |= INPUT_PICO_PEN;
      if (p & wpad_keymap[KEY_BUTTONB]) input.pad[0] |= INPUT_PICO_RED;

      /* PAGE index increment */
      if (p & wpad_keymap[KEY_BUTTONC]) pico_current = (pico_current + 1) & 7;

      break;
    }

    case DEVICE_TEREBI:
    {
      /* PEN screen position (x,y) */
      if (exp != WPAD_EXP_CLASSIC)
      {
        /* Wiimote IR */
        struct ir_t ir;
        WPAD_IR(chan, &ir);
        if (ir.valid)
        {
          input.analog[0][0] = ((ir.x + config.calx) * 250) / 640;
          input.analog[0][1] = ((ir.y + config.caly) * 250) / 480;
        }
      }
      else
      {
        /* Classic Controller analog stick */
        input.analog[0][0] += x / ANALOG_SENSITIVITY;
        input.analog[0][1] -= y / ANALOG_SENSITIVITY;

        /* Limits */
        if (input.analog[0][0] < 0)input.analog[0][0] = 0;
        else if (input.analog[0][0] > 250) input.analog[0][0] = 250;
        if (input.analog[0][1] < 0) input.analog[0][1] = 0;
        else if (input.analog[0][1] > 250) input.analog[0][1] = 250;
      }

      /* PEN button */
      if (p & wpad_keymap[KEY_BUTTONA]) input.pad[0] |= INPUT_BUTTON1;

      break;
    }

    case DEVICE_GRAPHIC_BOARD:
    {
      /* PEN screen position (x,y) */
      if (exp != WPAD_EXP_CLASSIC)
      {
        /* Wiimote IR */
        struct ir_t ir;
        WPAD_IR(chan, &ir);
        if (ir.valid)
        {
          input.analog[0][0] = ((ir.x + config.calx) * 255) / 640;
          input.analog[0][1] = ((ir.y + config.caly) * 255) / 480;
        }
      }
      else
      {
        /* Classic Controller analog stick */
        input.analog[0][0] += x / ANALOG_SENSITIVITY;
        input.analog[0][1] -= y / ANALOG_SENSITIVITY;

        /* Limits */
        if (input.analog[0][0] < 0)input.analog[0][0] = 0;
        else if (input.analog[0][0] > 255) input.analog[0][0] = 255;
        if (input.analog[0][1] < 0) input.analog[0][1] = 0;
        else if (input.analog[0][1] > 255) input.analog[0][1] = 255;
      }

      /* MODE Buttons */
      if (p & wpad_keymap[KEY_BUTTONA]) input.pad[0] |= INPUT_GRAPHIC_PEN;
      if (p & wpad_keymap[KEY_BUTTONB]) input.pad[0] |= INPUT_GRAPHIC_DO;
      if (p & wpad_keymap[KEY_BUTTONC]) input.pad[0] |= INPUT_GRAPHIC_MENU;

      break;
    }

    case DEVICE_ACTIVATOR:
    {
      /* Classic Controller only */
      if (exp == WPAD_EXP_CLASSIC)
      {
        /* Left stick */
        float mag = data->exp.classic.ljs.mag;
        float ang = data->exp.classic.ljs.ang;

        if (mag > 0.5)
        {
          /* 8 bottom sensors = 8 areas */
          if ((ang > 22.5) && (ang <= 67.5)) input.pad[i] |= INPUT_ACTIVATOR_2L;
          else if ((ang > 67.5) && (ang <= 112.5)) input.pad[i] |= INPUT_ACTIVATOR_3L;
          else if ((ang > 112.5) && (ang <= 157.5)) input.pad[i] |= INPUT_ACTIVATOR_4L;
          else if ((ang > 157.5) && (ang <= 202.5)) input.pad[i] |= INPUT_ACTIVATOR_5L;
          else if ((ang > 202.5) && (ang <= 247.5)) input.pad[i] |= INPUT_ACTIVATOR_6L;
          else if ((ang > 247.5) && (ang <= 292.5)) input.pad[i] |= INPUT_ACTIVATOR_7L;
          else if ((ang > 292.5) && (ang <= 337.5)) input.pad[i] |= INPUT_ACTIVATOR_8L;
          else input.pad[i] |= INPUT_ACTIVATOR_1L;
        }

        /* Right stick */
        mag = data->exp.classic.rjs.mag;
        ang = data->exp.classic.rjs.ang;

        if (mag > 0.5)
        {
          /* 8 top sensors = 8 areas */
          if ((ang > 22.5) && (ang <= 67.5)) input.pad[i] |= INPUT_ACTIVATOR_2U;
          else if ((ang > 67.5) && (ang <= 112.5)) input.pad[i] |= INPUT_ACTIVATOR_3U;
          else if ((ang > 112.5) && (ang <= 157.5)) input.pad[i] |= INPUT_ACTIVATOR_4U;
          else if ((ang > 157.5) && (ang <= 202.5)) input.pad[i] |= INPUT_ACTIVATOR_5U;
          else if ((ang > 202.5) && (ang <= 247.5)) input.pad[i] |= INPUT_ACTIVATOR_6U;
          else if ((ang > 247.5) && (ang <= 292.5)) input.pad[i] |= INPUT_ACTIVATOR_7U;
          else if ((ang > 292.5) && (ang <= 337.5)) input.pad[i] |= INPUT_ACTIVATOR_8U;
          else input.pad[i] |= INPUT_ACTIVATOR_1U;
        }
      }

      break;
    }
  }
}