Beispiel #1
0
static int zarch_iterate(enum menu_action action)
{
   int ret = 0;
   int         action_id;
   menu_entry_t entry;
   zui_t *zui           = NULL;
   menu_handle_t *menu  = menu_driver_get_ptr();
   enum menu_action act = (enum menu_action)action;
   bool perform_action  = true;

   if (!menu)
      return 0;

   zui      = (zui_t*)menu->userdata;

   if (!zui)
      return -1;
   if (!menu_navigation_ctl(MENU_NAVIGATION_CTL_GET_SELECTION, &action_id))
      return 0;

   BIT64_SET(menu->state, MENU_STATE_RENDER_FRAMEBUFFER);
   BIT64_SET(menu->state, MENU_STATE_BLIT);

   menu_entry_get(&entry, 0, action_id, NULL, false);

   if (action_id >= 0)
      zui->pending_selection = action_id;
   
   if (zui->pending_action_ok.enable)
   {
      menu_entry_get(&entry, 0, zui->pending_action_ok.idx, NULL, false);
      zui->pending_action_ok.enable = false;
      
      act               = MENU_ACTION_OK;
      action_id    = zui->pending_action_ok.idx;
      zui->pending_action_ok.idx = 0;
   }
   else
   {
      zui->action       = act;
   }

   if (perform_action)
      ret = menu_entry_action(&entry, action_id, act);

   if (zui->time_to_exit)
   {
      zui->time_to_exit = false;
      return -1;
   }
   if (zui->time_to_quit)
   {
      zui->time_to_quit = false;
      if (!event_command(EVENT_CMD_QUIT))
         return -1;
      return 0;
   }

   return ret;
}
Beispiel #2
0
static void linuxraw_poll_pad(struct linuxraw_joypad *pad)
{
   struct js_event event;
   
   while (read(pad->fd, &event, sizeof(event)) == (ssize_t)sizeof(event))
   {
      unsigned type = event.type & ~JS_EVENT_INIT;

      switch (type)
      {
         case JS_EVENT_BUTTON:
            if (event.number < NUM_BUTTONS)
            {
               if (event.value)
                  BIT64_SET(pad->buttons, event.number);
               else
                  BIT64_CLEAR(pad->buttons, event.number);
            }
            break;

         case JS_EVENT_AXIS:
            if (event.number < NUM_AXES)
               pad->axes[event.number] = event.value;
            break;
      }
   }
}
Beispiel #3
0
retro_input_t input_driver_keys_pressed(uint64_t *device_type)
{
   int key;
   retro_input_t                ret = 0;
   driver_t                 *driver = driver_get_ptr();
   const input_driver_t      *input = input_get_ptr(driver);

   for (key = 0; key < RARCH_BIND_LIST_END; key++)
   {
      bool state = false;
      enum input_device_type device = INPUT_DEVICE_TYPE_NONE;
      if ((!driver->block_libretro_input && ((key < RARCH_FIRST_META_KEY)))
            || !driver->block_hotkey)
         state = input->key_pressed(driver->input_data, key, &device);

      if (key >= RARCH_FIRST_META_KEY)
         state |= input->meta_key_pressed(driver->input_data, key, &device);

      if (device == INPUT_DEVICE_TYPE_JOYPAD)
         BIT64_SET(*device_type, key);

#ifdef HAVE_OVERLAY
      state |= input_overlay_key_pressed(key);
#endif

#ifdef HAVE_COMMAND
      if (driver->command)
         state |= rarch_cmd_get(driver->command, key);
#endif

      if (state)
         ret |= (UINT64_C(1) << key);
   }
   return ret;
}
Beispiel #4
0
static void psp_joypad_poll(void)
{
   int32_t ret;
   unsigned i, j, k;
   SceCtrlData state_tmp;
   unsigned players_count = 1;

#ifdef PSP
   sceCtrlSetSamplingCycle(0);
#endif
   sceCtrlSetSamplingMode(DEFAULT_SAMPLING_MODE);

   ret = CtrlPeekBufferPositive(0, &state_tmp, 1);

   for (i = 0; i < players_count; i++)
   {
#ifdef HAVE_KERNEL_PRX
      state_tmp.Buttons = (state_tmp.Buttons & 0x0000FFFF)
         | (read_system_buttons() & 0xFFFF0000);
#endif
      (void)ret;

      analog_state[i][0][0] = analog_state[i][0][1] =
         analog_state[i][1][0] = analog_state[i][1][1] = 0;
      pad_state[i] = 0;
      pad_state[i] |= (STATE_BUTTON(state_tmp) & PSP_CTRL_LEFT) ? (UINT64_C(1) << RETRO_DEVICE_ID_JOYPAD_LEFT) : 0;
      pad_state[i] |= (STATE_BUTTON(state_tmp) & PSP_CTRL_DOWN) ? (UINT64_C(1) << RETRO_DEVICE_ID_JOYPAD_DOWN) : 0;
      pad_state[i] |= (STATE_BUTTON(state_tmp) & PSP_CTRL_RIGHT) ? (UINT64_C(1) << RETRO_DEVICE_ID_JOYPAD_RIGHT) : 0;
      pad_state[i] |= (STATE_BUTTON(state_tmp) & PSP_CTRL_UP) ? (UINT64_C(1) << RETRO_DEVICE_ID_JOYPAD_UP) : 0;
      pad_state[i] |= (STATE_BUTTON(state_tmp) & PSP_CTRL_START) ? (UINT64_C(1) << RETRO_DEVICE_ID_JOYPAD_START) : 0;
      pad_state[i] |= (STATE_BUTTON(state_tmp) & PSP_CTRL_SELECT) ? (UINT64_C(1) << RETRO_DEVICE_ID_JOYPAD_SELECT) : 0;
      pad_state[i] |= (STATE_BUTTON(state_tmp) & PSP_CTRL_TRIANGLE) ? (UINT64_C(1) << RETRO_DEVICE_ID_JOYPAD_X) : 0;
      pad_state[i] |= (STATE_BUTTON(state_tmp) & PSP_CTRL_SQUARE) ? (UINT64_C(1) << RETRO_DEVICE_ID_JOYPAD_Y) : 0;
      pad_state[i] |= (STATE_BUTTON(state_tmp) & PSP_CTRL_CROSS) ? (UINT64_C(1) << RETRO_DEVICE_ID_JOYPAD_B) : 0;
      pad_state[i] |= (STATE_BUTTON(state_tmp) & PSP_CTRL_CIRCLE) ? (UINT64_C(1) << RETRO_DEVICE_ID_JOYPAD_A) : 0;
      pad_state[i] |= (STATE_BUTTON(state_tmp) & PSP_CTRL_R) ? (UINT64_C(1) << RETRO_DEVICE_ID_JOYPAD_R) : 0;
      pad_state[i] |= (STATE_BUTTON(state_tmp) & PSP_CTRL_L) ? (UINT64_C(1) << RETRO_DEVICE_ID_JOYPAD_L) : 0;

      analog_state[i][RETRO_DEVICE_INDEX_ANALOG_LEFT] [RETRO_DEVICE_ID_ANALOG_X] = (int16_t)(STATE_ANALOGLX(state_tmp)-128) * 256;
      analog_state[i][RETRO_DEVICE_INDEX_ANALOG_LEFT] [RETRO_DEVICE_ID_ANALOG_Y] = (int16_t)(STATE_ANALOGLY(state_tmp)-128) * 256;
#if defined(SN_TARGET_PSP2) || defined(VITA)
      analog_state[i][RETRO_DEVICE_INDEX_ANALOG_RIGHT][RETRO_DEVICE_ID_ANALOG_X] = (int16_t)(STATE_ANALOGRX(state_tmp)-128) * 256;
      analog_state[i][RETRO_DEVICE_INDEX_ANALOG_RIGHT][RETRO_DEVICE_ID_ANALOG_Y] = (int16_t)(STATE_ANALOGRY(state_tmp)-128) * 256;
#endif

      for (j = 0; j < 2; j++)
         for (k = 0; k < 2; k++)
            if (analog_state[i][j][k] == -0x8000)
               analog_state[i][j][k] = -0x7fff;
   }

   BIT64_CLEAR(lifecycle_state, RARCH_MENU_TOGGLE);

#ifdef HAVE_KERNEL_PRX
   if (STATE_BUTTON(state_tmp) & PSP_CTRL_NOTE)
      BIT64_SET(lifecycle_state, RARCH_MENU_TOGGLE);
#endif
}
Beispiel #5
0
/**
 * input_flush:
 * @input                : input sample for this frame
 *
 * Resets input sample.
 *
 * Returns: always true (1).
 **/
static bool input_flush(runloop_t *runloop, retro_input_t *input)
{
   *input = 0;

   /* If core was paused before entering menu, evoke
    * pause toggle to wake it up. */
   if (runloop->is_paused)
      BIT64_SET(*input, RARCH_PAUSE_TOGGLE);

   return true;
}
Beispiel #6
0
static void ctr_joypad_poll(void)
{
   int32_t ret;
   unsigned i, j;
   uint32_t state_tmp;
   circlePosition state_tmp_analog;

   hidScanInput();

   state_tmp = hidKeysHeld();
   hidCircleRead(&state_tmp_analog);

   analog_state[0][0][0] = analog_state[0][0][1] =
      analog_state[0][1][0] = analog_state[0][1][1] = 0;
   pad_state = 0;
   pad_state |= (state_tmp & KEY_DLEFT) ? (UINT64_C(1) << RETRO_DEVICE_ID_JOYPAD_LEFT) : 0;
   pad_state |= (state_tmp & KEY_DDOWN) ? (UINT64_C(1) << RETRO_DEVICE_ID_JOYPAD_DOWN) : 0;
   pad_state |= (state_tmp & KEY_DRIGHT) ? (UINT64_C(1) << RETRO_DEVICE_ID_JOYPAD_RIGHT) : 0;
   pad_state |= (state_tmp & KEY_DUP) ? (UINT64_C(1) << RETRO_DEVICE_ID_JOYPAD_UP) : 0;
   pad_state |= (state_tmp & KEY_START) ? (UINT64_C(1) << RETRO_DEVICE_ID_JOYPAD_START) : 0;
   pad_state |= (state_tmp & KEY_SELECT) ? (UINT64_C(1) << RETRO_DEVICE_ID_JOYPAD_SELECT) : 0;
   pad_state |= (state_tmp & KEY_X) ? (UINT64_C(1) << RETRO_DEVICE_ID_JOYPAD_X) : 0;
   pad_state |= (state_tmp & KEY_Y) ? (UINT64_C(1) << RETRO_DEVICE_ID_JOYPAD_Y) : 0;
   pad_state |= (state_tmp & KEY_B) ? (UINT64_C(1) << RETRO_DEVICE_ID_JOYPAD_B) : 0;
   pad_state |= (state_tmp & KEY_A) ? (UINT64_C(1) << RETRO_DEVICE_ID_JOYPAD_A) : 0;
   pad_state |= (state_tmp & KEY_R) ? (UINT64_C(1) << RETRO_DEVICE_ID_JOYPAD_R) : 0;
   pad_state |= (state_tmp & KEY_L) ? (UINT64_C(1) << RETRO_DEVICE_ID_JOYPAD_L) : 0;

   analog_state[0][RETRO_DEVICE_INDEX_ANALOG_LEFT] [RETRO_DEVICE_ID_ANALOG_X] =  (state_tmp_analog.dx * 200);
   analog_state[0][RETRO_DEVICE_INDEX_ANALOG_LEFT] [RETRO_DEVICE_ID_ANALOG_Y] = -(state_tmp_analog.dy * 200);

   for (i = 0; i < 2; i++)
      for (j = 0; j < 2; j++)
         if (analog_state[0][i][j] == -0x8000)
            analog_state[0][i][j] = -0x7fff;

   BIT64_CLEAR(lifecycle_state, RARCH_MENU_TOGGLE);

   if(state_tmp & KEY_TOUCH)
      BIT64_SET(lifecycle_state, RARCH_MENU_TOGGLE);

   /* panic button */
   if((state_tmp & KEY_START) &&
      (state_tmp & KEY_SELECT) &&
      (state_tmp & KEY_L) &&
      (state_tmp & KEY_R))
      event_command(EVENT_CMD_QUIT);

}
Beispiel #7
0
static void ctr_joypad_poll(void)
{
   uint32_t state_tmp;
   circlePosition state_tmp_left_analog, state_tmp_right_analog;
   touchPosition state_tmp_touch;

   hidScanInput();

   state_tmp = hidKeysHeld();
   hidCircleRead(&state_tmp_left_analog);
   irrstCstickRead(&state_tmp_right_analog);
   hidTouchRead(&state_tmp_touch);

   pad_state = 0;
   pad_state |= (state_tmp & KEY_DLEFT) ? (UINT64_C(1) << RETRO_DEVICE_ID_JOYPAD_LEFT) : 0;
   pad_state |= (state_tmp & KEY_DDOWN) ? (UINT64_C(1) << RETRO_DEVICE_ID_JOYPAD_DOWN) : 0;
   pad_state |= (state_tmp & KEY_DRIGHT) ? (UINT64_C(1) << RETRO_DEVICE_ID_JOYPAD_RIGHT) : 0;
   pad_state |= (state_tmp & KEY_DUP) ? (UINT64_C(1) << RETRO_DEVICE_ID_JOYPAD_UP) : 0;
   pad_state |= (state_tmp & KEY_START) ? (UINT64_C(1) << RETRO_DEVICE_ID_JOYPAD_START) : 0;
   pad_state |= (state_tmp & KEY_SELECT) ? (UINT64_C(1) << RETRO_DEVICE_ID_JOYPAD_SELECT) : 0;
   pad_state |= (state_tmp & KEY_X) ? (UINT64_C(1) << RETRO_DEVICE_ID_JOYPAD_X) : 0;
   pad_state |= (state_tmp & KEY_Y) ? (UINT64_C(1) << RETRO_DEVICE_ID_JOYPAD_Y) : 0;
   pad_state |= (state_tmp & KEY_B) ? (UINT64_C(1) << RETRO_DEVICE_ID_JOYPAD_B) : 0;
   pad_state |= (state_tmp & KEY_A) ? (UINT64_C(1) << RETRO_DEVICE_ID_JOYPAD_A) : 0;
   pad_state |= (state_tmp & KEY_R) ? (UINT64_C(1) << RETRO_DEVICE_ID_JOYPAD_R) : 0;
   pad_state |= (state_tmp & KEY_L) ? (UINT64_C(1) << RETRO_DEVICE_ID_JOYPAD_L) : 0;
   pad_state |= (state_tmp & KEY_ZR) ? (UINT64_C(1) << RETRO_DEVICE_ID_JOYPAD_R2) : 0;
   pad_state |= (state_tmp & KEY_ZL) ? (UINT64_C(1) << RETRO_DEVICE_ID_JOYPAD_L2) : 0;

   analog_state[0][RETRO_DEVICE_INDEX_ANALOG_LEFT] [RETRO_DEVICE_ID_ANALOG_X]  =  ctr_joypad_fix_range(state_tmp_left_analog.dx);
   analog_state[0][RETRO_DEVICE_INDEX_ANALOG_LEFT] [RETRO_DEVICE_ID_ANALOG_Y]  = -ctr_joypad_fix_range(state_tmp_left_analog.dy);
   analog_state[0][RETRO_DEVICE_INDEX_ANALOG_RIGHT] [RETRO_DEVICE_ID_ANALOG_X] =  ctr_joypad_fix_range(state_tmp_right_analog.dx);
   analog_state[0][RETRO_DEVICE_INDEX_ANALOG_RIGHT] [RETRO_DEVICE_ID_ANALOG_Y] = -ctr_joypad_fix_range(state_tmp_right_analog.dy);

   BIT64_CLEAR(lifecycle_state, RARCH_MENU_TOGGLE);

   if((state_tmp & KEY_TOUCH) && (state_tmp_touch.py > 120))
      BIT64_SET(lifecycle_state, RARCH_MENU_TOGGLE);

   /* panic button */
   if((state_tmp & KEY_START) &&
      (state_tmp & KEY_SELECT) &&
      (state_tmp & KEY_L) &&
      (state_tmp & KEY_R))
      command_event(CMD_EVENT_QUIT, NULL);

}
Beispiel #8
0
int menu_iterate_render(void)
{
   bool is_idle;
   const menu_ctx_driver_t *driver = menu_ctx_driver_get_ptr();
   menu_handle_t *menu       = menu_driver_get_ptr();

   if (!menu)
      return -1;

   if (BIT64_GET(menu->state, MENU_STATE_RENDER_FRAMEBUFFER) != BIT64_GET(menu->state, MENU_STATE_RENDER_MESSAGEBOX))
      BIT64_SET(menu->state, MENU_STATE_RENDER_FRAMEBUFFER);

   if (BIT64_GET(menu->state, MENU_STATE_RENDER_FRAMEBUFFER))
      menu_display_ctl(MENU_DISPLAY_CTL_SET_FRAMEBUFFER_DIRTY_FLAG, NULL);

   if (BIT64_GET(menu->state, MENU_STATE_RENDER_MESSAGEBOX) && menu->menu_state.msg[0] != '\0')
   {
      if (driver->render_messagebox)
         driver->render_messagebox(menu->menu_state.msg);

      if (ui_companion_is_on_foreground())
      {
         const ui_companion_driver_t *ui = ui_companion_get_ptr();
         if (ui->render_messagebox)
            ui->render_messagebox(menu->menu_state.msg);
      }
   }
      
   if (BIT64_GET(menu->state, MENU_STATE_BLIT))
   {
      menu_animation_ctl(MENU_ANIMATION_CTL_UPDATE_TIME, NULL);
      if (driver->render)
         driver->render();
   }

   rarch_main_ctl(RARCH_MAIN_CTL_IS_IDLE, &is_idle);

   if (menu_driver_alive() && !is_idle)
      menu_display_ctl(MENU_DISPLAY_CTL_LIBRETRO, NULL);

   menu_driver_set_texture();

   menu->state               = 0;

   return 0;
}
Beispiel #9
0
static void wiiu_joypad_poll(void)
{
   VPADStatus vpad;
   VPADReadError vpadError;
   VPADRead(0, &vpad, 1, &vpadError);

   if(vpadError)
      return;

   pad_state = 0;
   pad_state |= (vpad.hold & VPAD_BUTTON_LEFT) ? (UINT64_C(1) << RETRO_DEVICE_ID_JOYPAD_LEFT) : 0;
   pad_state |= (vpad.hold & VPAD_BUTTON_DOWN) ? (UINT64_C(1) << RETRO_DEVICE_ID_JOYPAD_DOWN) : 0;
   pad_state |= (vpad.hold & VPAD_BUTTON_RIGHT) ? (UINT64_C(1) << RETRO_DEVICE_ID_JOYPAD_RIGHT) : 0;
   pad_state |= (vpad.hold & VPAD_BUTTON_UP) ? (UINT64_C(1) << RETRO_DEVICE_ID_JOYPAD_UP) : 0;
   pad_state |= (vpad.hold & VPAD_BUTTON_PLUS) ? (UINT64_C(1) << RETRO_DEVICE_ID_JOYPAD_START) : 0;
   pad_state |= (vpad.hold & VPAD_BUTTON_MINUS) ? (UINT64_C(1) << RETRO_DEVICE_ID_JOYPAD_SELECT) : 0;
   pad_state |= (vpad.hold & VPAD_BUTTON_X) ? (UINT64_C(1) << RETRO_DEVICE_ID_JOYPAD_X) : 0;
   pad_state |= (vpad.hold & VPAD_BUTTON_Y) ? (UINT64_C(1) << RETRO_DEVICE_ID_JOYPAD_Y) : 0;
   pad_state |= (vpad.hold & VPAD_BUTTON_B) ? (UINT64_C(1) << RETRO_DEVICE_ID_JOYPAD_B) : 0;
   pad_state |= (vpad.hold & VPAD_BUTTON_A) ? (UINT64_C(1) << RETRO_DEVICE_ID_JOYPAD_A) : 0;
   pad_state |= (vpad.hold & VPAD_BUTTON_R) ? (UINT64_C(1) << RETRO_DEVICE_ID_JOYPAD_R) : 0;
   pad_state |= (vpad.hold & VPAD_BUTTON_L) ? (UINT64_C(1) << RETRO_DEVICE_ID_JOYPAD_L) : 0;
   pad_state |= (vpad.hold & VPAD_BUTTON_ZR) ? (UINT64_C(1) << RETRO_DEVICE_ID_JOYPAD_R2) : 0;
   pad_state |= (vpad.hold & VPAD_BUTTON_ZL) ? (UINT64_C(1) << RETRO_DEVICE_ID_JOYPAD_L2) : 0;
   pad_state |= (vpad.hold & VPAD_BUTTON_STICK_R) ? (UINT64_C(1) << RETRO_DEVICE_ID_JOYPAD_R3) : 0;
   pad_state |= (vpad.hold & VPAD_BUTTON_STICK_L) ? (UINT64_C(1) << RETRO_DEVICE_ID_JOYPAD_L3) : 0;

   analog_state[0][RETRO_DEVICE_INDEX_ANALOG_LEFT] [RETRO_DEVICE_ID_ANALOG_X]  =  vpad.leftStick.x * 0x7FF0;
   analog_state[0][RETRO_DEVICE_INDEX_ANALOG_LEFT] [RETRO_DEVICE_ID_ANALOG_Y]  = -vpad.leftStick.y * 0x7FF0;
   analog_state[0][RETRO_DEVICE_INDEX_ANALOG_RIGHT] [RETRO_DEVICE_ID_ANALOG_X] =  vpad.rightStick.x * 0x7FF0;
   analog_state[0][RETRO_DEVICE_INDEX_ANALOG_RIGHT] [RETRO_DEVICE_ID_ANALOG_Y] = -vpad.rightStick.y * 0x7FF0;

   BIT64_CLEAR(lifecycle_state, RARCH_MENU_TOGGLE);

   if(((vpad.tpNormal.touched) && (vpad.tpNormal.x > 200) && (vpad.tpNormal.validity) == 0) ||
      (vpad.trigger & VPAD_BUTTON_HOME))
      BIT64_SET(lifecycle_state, RARCH_MENU_TOGGLE);

   /* panic button */
   if((vpad.hold & VPAD_BUTTON_R) &&
      (vpad.hold & VPAD_BUTTON_L) &&
      (vpad.hold & VPAD_BUTTON_STICK_R) &&
      (vpad.hold & VPAD_BUTTON_STICK_L))
      command_event(CMD_EVENT_QUIT, NULL);
}
Beispiel #10
0
int menu_iterate_render(void *data, void *userdata)
{
   menu_handle_t *menu             = (menu_handle_t*)data;

   if (!menu)
      return -1;

   if (BIT64_GET(menu->state, MENU_STATE_RENDER_FRAMEBUFFER) 
         != BIT64_GET(menu->state, MENU_STATE_RENDER_MESSAGEBOX))
      BIT64_SET(menu->state, MENU_STATE_RENDER_FRAMEBUFFER);

   if (BIT64_GET(menu->state, MENU_STATE_RENDER_FRAMEBUFFER))
      menu_display_ctl(MENU_DISPLAY_CTL_SET_FRAMEBUFFER_DIRTY_FLAG, NULL);

   if (BIT64_GET(menu->state, MENU_STATE_RENDER_MESSAGEBOX) 
         && !string_is_empty(menu->menu_state.msg))
   {
      menu_driver_ctl(RARCH_MENU_CTL_RENDER_MESSAGEBOX, NULL);

      if (ui_companion_is_on_foreground())
      {
         const ui_companion_driver_t *ui = ui_companion_get_ptr();
         if (ui->render_messagebox)
            ui->render_messagebox(menu->menu_state.msg);
      }
   }
      
   if (BIT64_GET(menu->state, MENU_STATE_BLIT))
   {
      menu_animation_ctl(MENU_ANIMATION_CTL_UPDATE_TIME, NULL);
      menu_driver_ctl(RARCH_MENU_CTL_BLIT_RENDER, NULL);
   }

   if (menu_driver_ctl(RARCH_MENU_CTL_IS_ALIVE, NULL) 
         && !runloop_ctl(RUNLOOP_CTL_IS_IDLE, NULL))
      menu_display_ctl(MENU_DISPLAY_CTL_LIBRETRO, NULL);

   menu_driver_ctl(RARCH_MENU_CTL_SET_TEXTURE, NULL);

   menu->state               = 0;

   return 0;
}
Beispiel #11
0
static void apple_hid_device_input_callback(void *data, IOReturn result,
      void* sender, IOHIDValueRef value)
{
   driver_t                  *driver = driver_get_ptr();
   apple_input_data_t         *apple = (apple_input_data_t*)driver->input_data;
   struct apple_hid_adapter *adapter = (struct apple_hid_adapter*)data;
   IOHIDElementRef element           = IOHIDValueGetElement(value);
   uint32_t type                     = IOHIDElementGetType(element);
   uint32_t page                     = IOHIDElementGetUsagePage(element);
   uint32_t use                      = IOHIDElementGetUsage(element);

   if (type != kIOHIDElementTypeInput_Misc)
      if (type != kIOHIDElementTypeInput_Button)
         if (type != kIOHIDElementTypeInput_Axis)
            return;

   /* Joystick handler.
    * TODO: Can GamePad work the same? */

   switch (page)
   {
      case kHIDPage_GenericDesktop:
         switch (type)
         {
            case kIOHIDElementTypeInput_Misc:
               switch (use)
               {
                  case kHIDUsage_GD_Hatswitch:
                     break;
                  default:
                     {
                        int i;
                        static const uint32_t axis_use_ids[4] = { 48, 49, 50, 53 };

                        for (i = 0; i < 4; i ++)
                        {
                           CFIndex min   = IOHIDElementGetPhysicalMin(element);
                           CFIndex max   = IOHIDElementGetPhysicalMax(element) - min;
                           CFIndex state = IOHIDValueGetIntegerValue(value) - min;
                           float val     = (float)state / (float)max;

                           if (use != axis_use_ids[i])
                              continue;

                           apple->axes[adapter->slot][i] =
                              ((val * 2.0f) - 1.0f) * 32767.0f;
                        }
                     }
                     break;
               }
               break;
         }
         break;
      case kHIDPage_Button:
         switch (type)
         {
            case kIOHIDElementTypeInput_Button:
               {
                  CFIndex state = IOHIDValueGetIntegerValue(value);
                  unsigned id = use - 1;

                  if (state)
                     BIT64_SET(apple->buttons[adapter->slot], id);
                  else
                     BIT64_CLEAR(apple->buttons[adapter->slot], id);
               }
               break;
         }
         break;
   }
}
Beispiel #12
0
/**
 * rarch_main_iterate:
 *
 * Run Libretro core in RetroArch for one frame.
 *
 * Returns: 0 on success, 1 if we have to wait until button input in order
 * to wake up the loop, -1 if we forcibly quit out of the RetroArch iteration loop.
 **/
int rarch_main_iterate(unsigned *sleep_ms)
{
   int ret;
   unsigned i;
   retro_input_t trigger_input;
   event_cmd_state_t    cmd;
   retro_time_t current, target, to_sleep_ms;
   static retro_input_t last_input = 0;
   driver_t *driver                = driver_get_ptr();
   settings_t *settings            = config_get_ptr();
   global_t   *global              = global_get_ptr();
   retro_input_t input             = input_keys_pressed(driver, settings, global);
   rarch_system_info_t *system     = rarch_system_info_get_ptr();
   retro_input_t old_input         = last_input;
   last_input                      = input;

   if (driver->flushing_input)
   {
      driver->flushing_input = false;
      if (input)
      {
         input = 0;

         /* If core was paused before entering menu, evoke
          * pause toggle to wake it up. */
         if (main_is_paused)
            BIT64_SET(input, RARCH_PAUSE_TOGGLE);
         driver->flushing_input = true;
      }
   }

   trigger_input = input & ~old_input;

   rarch_main_cmd_get_state(driver, settings, &cmd, input, old_input, trigger_input);

   if (system->frame_time.callback)
   {
      /* Updates frame timing if frame timing callback is in use by the core.
       * Limits frame time if fast forward ratio throttle is enabled. */

      retro_time_t current     = retro_get_time_usec();
      retro_time_t delta       = current - system->frame_time_last;
      bool is_locked_fps       = (main_is_paused || driver->nonblock_state) |
         !!driver->recording_data;

      if (!system->frame_time_last || is_locked_fps)
         delta = system->frame_time.reference;

      if (!is_locked_fps && main_is_slowmotion)
         delta /= settings->slowmotion_ratio;

      system->frame_time_last = current;

      if (is_locked_fps)
         system->frame_time_last = 0;

      system->frame_time.callback(delta);
   }

   if (cmd.overlay_next_pressed)
      event_command(EVENT_CMD_OVERLAY_NEXT);

   if (!main_is_paused || menu_driver_alive())
   {
      if (cmd.fullscreen_toggle)
         event_command(EVENT_CMD_FULLSCREEN_TOGGLE);
   }

   if (cmd.grab_mouse_pressed)
      event_command(EVENT_CMD_GRAB_MOUSE_TOGGLE);

#ifdef HAVE_MENU
   if (cmd.menu_pressed || (global->inited.core.type == CORE_TYPE_DUMMY))
   {
      if (menu_driver_alive())
      {
         if (global->inited.main && (global->inited.core.type != CORE_TYPE_DUMMY))
            rarch_ctl(RARCH_ACTION_STATE_MENU_RUNNING_FINISHED, NULL);
      }
      else
         rarch_ctl(RARCH_ACTION_STATE_MENU_RUNNING, NULL);
   }
#endif

#ifdef HAVE_OVERLAY
   rarch_main_iterate_linefeed_overlay(driver, settings);
#endif

   ret = rarch_main_iterate_time_to_exit(&cmd);

   if (ret != 1)
      return -1;


#ifdef HAVE_MENU
   if (menu_driver_alive())
   {
      if (menu_driver_iterate((enum menu_action)menu_input_frame(input, trigger_input)) == -1)
         rarch_ctl(RARCH_ACTION_STATE_MENU_RUNNING_FINISHED, NULL);

      if (!input && settings->menu.pause_libretro)
        return 1;
      goto end;
   }
#endif

   if (!rarch_main_ctl(RARCH_MAIN_CTL_CHECK_STATE, &cmd))
   {
      /* RetroArch has been paused. */
      driver->retro_ctx.poll_cb();
      *sleep_ms = 10;
      return 1;
   }

#if defined(HAVE_THREADS)
   lock_autosave();
#endif

#ifdef HAVE_NETPLAY
   if (driver->netplay_data)
      netplay_pre_frame((netplay_t*)driver->netplay_data);
#endif

   if (global->bsv.movie)
      bsv_movie_set_frame_start(global->bsv.movie);

   if (system->camera_callback.caps)
      driver_camera_poll();

   /* Update binds for analog dpad modes. */
   for (i = 0; i < settings->input.max_users; i++)
   {
      if (!settings->input.analog_dpad_mode[i])
         continue;

      input_push_analog_dpad(settings->input.binds[i],
            settings->input.analog_dpad_mode[i]);
      input_push_analog_dpad(settings->input.autoconf_binds[i],
            settings->input.analog_dpad_mode[i]);
   }

   if ((settings->video.frame_delay > 0) && !driver->nonblock_state)
      retro_sleep(settings->video.frame_delay);

   /* Run libretro for one frame. */
   core.retro_run();

#ifdef HAVE_CHEEVOS
   /* Test the achievements. */
   cheevos_test();
#endif

   for (i = 0; i < settings->input.max_users; i++)
   {
      if (!settings->input.analog_dpad_mode[i])
         continue;

      input_pop_analog_dpad(settings->input.binds[i]);
      input_pop_analog_dpad(settings->input.autoconf_binds[i]);
   }

   if (global->bsv.movie)
      bsv_movie_set_frame_end(global->bsv.movie);

#ifdef HAVE_NETPLAY
   if (driver->netplay_data)
      netplay_post_frame((netplay_t*)driver->netplay_data);
#endif

#if defined(HAVE_THREADS)
   unlock_autosave();
#endif

#ifdef HAVE_MENU
end:
#endif
   if (!settings->fastforward_ratio)
      return 0;

   current                        = retro_get_time_usec();
   target                         = frame_limit_last_time + frame_limit_minimum_time;
   to_sleep_ms                    = (target - current) / 1000;

   if (to_sleep_ms > 0)
   {
      *sleep_ms = (unsigned)to_sleep_ms;
      /* Combat jitter a bit. */
      frame_limit_last_time += frame_limit_minimum_time;
      return 1;
   }

   frame_limit_last_time  = retro_get_time_usec();

   return 0;
}
Beispiel #13
0
static void gx_joypad_poll(void)
{
   unsigned i, j, port;
   uint8_t gcpad    = 0;

   pad_state[0] = 0;
   pad_state[1] = 0;
   pad_state[2] = 0;
   pad_state[3] = 0;

   gcpad = PAD_ScanPads();

#ifdef HW_RVL
   WPAD_ReadPending(WPAD_CHAN_ALL, NULL);
#endif

   for (port = 0; port < MAX_PADS; port++)
   {
      uint32_t down = 0, ptype = WPAD_EXP_NOCONTROLLER;
      uint64_t *state_cur = &pad_state[port];

      if (gcpad & (1 << port))
      {
         int16_t ls_x, ls_y, rs_x, rs_y;
         uint64_t menu_combo = 0;

         down = PAD_ButtonsHeld(port);

         *state_cur |= (down & PAD_BUTTON_A) ? (UINT64_C(1) << GX_GC_A) : 0;
         *state_cur |= (down & PAD_BUTTON_B) ? (UINT64_C(1) << GX_GC_B) : 0;
         *state_cur |= (down & PAD_BUTTON_X) ? (UINT64_C(1) << GX_GC_X) : 0;
         *state_cur |= (down & PAD_BUTTON_Y) ? (UINT64_C(1) << GX_GC_Y) : 0;
         *state_cur |= (down & PAD_BUTTON_UP) ? (UINT64_C(1) << GX_GC_UP) : 0;
         *state_cur |= (down & PAD_BUTTON_DOWN) ? (UINT64_C(1) << GX_GC_DOWN) : 0;
         *state_cur |= (down & PAD_BUTTON_LEFT) ? (UINT64_C(1) << GX_GC_LEFT) : 0;
         *state_cur |= (down & PAD_BUTTON_RIGHT) ? (UINT64_C(1) << GX_GC_RIGHT) : 0;
         *state_cur |= (down & PAD_BUTTON_START) ? (UINT64_C(1) << GX_GC_START) : 0;
         *state_cur |= (down & PAD_TRIGGER_Z) ? (UINT64_C(1) << GX_GC_Z_TRIGGER) : 0;
         *state_cur |= ((down & PAD_TRIGGER_L) || PAD_TriggerL(port) > 127) ? (UINT64_C(1) << GX_GC_L_TRIGGER) : 0;
         *state_cur |= ((down & PAD_TRIGGER_R) || PAD_TriggerR(port) > 127) ? (UINT64_C(1) << GX_GC_R_TRIGGER) : 0;

         ls_x = (int16_t)PAD_StickX(port) * 256;
         ls_y = (int16_t)PAD_StickY(port) * -256;
         rs_x = (int16_t)PAD_SubStickX(port) * 256;
         rs_y = (int16_t)PAD_SubStickY(port) * -256;

         analog_state[port][RETRO_DEVICE_INDEX_ANALOG_LEFT][RETRO_DEVICE_ID_ANALOG_X] = ls_x;
         analog_state[port][RETRO_DEVICE_INDEX_ANALOG_LEFT][RETRO_DEVICE_ID_ANALOG_Y] = ls_y;
         analog_state[port][RETRO_DEVICE_INDEX_ANALOG_RIGHT][RETRO_DEVICE_ID_ANALOG_X] = rs_x;
         analog_state[port][RETRO_DEVICE_INDEX_ANALOG_RIGHT][RETRO_DEVICE_ID_ANALOG_Y] = rs_y;

         menu_combo = (UINT64_C(1) << GX_GC_START) | (UINT64_C(1) << GX_GC_Z_TRIGGER) |
                      (UINT64_C(1) << GX_GC_L_TRIGGER) | (UINT64_C(1) << GX_GC_R_TRIGGER);

         if ((*state_cur & menu_combo) == menu_combo)
            *state_cur |= (UINT64_C(1) << GX_GC_HOME);

         ptype = WPAD_EXP_GAMECUBE;
      }
#ifdef HW_RVL
#ifdef HAVE_LIBSICKSAXIS
      else if (port < USB_SLOTS && ss_is_ready(&sixaxis[port]))/* Only defined 1 port for now */
      {
         int16_t ls_x, ls_y, rs_x, rs_y;

         ss_read_pad(&sixaxis[port]);

         *state_cur |= (sixaxis[port].pad.buttons.PS)       ? (UINT64_C(1) << GX_SIXAXIS_PS) : 0;
         *state_cur |= (sixaxis[port].pad.buttons.cross)    ? (UINT64_C(1) << GX_SIXAXIS_CROSS) : 0;
         *state_cur |= (sixaxis[port].pad.buttons.square)   ? (UINT64_C(1) << GX_SIXAXIS_SQUARE) : 0;
         *state_cur |= (sixaxis[port].pad.buttons.select)   ? (UINT64_C(1) << GX_SIXAXIS_SELECT) : 0;
         *state_cur |= (sixaxis[port].pad.buttons.start)    ? (UINT64_C(1) << GX_SIXAXIS_START) : 0;
         *state_cur |= (sixaxis[port].pad.buttons.up)       ? (UINT64_C(1) << GX_SIXAXIS_UP) : 0;
         *state_cur |= (sixaxis[port].pad.buttons.down)     ? (UINT64_C(1) << GX_SIXAXIS_DOWN) : 0;
         *state_cur |= (sixaxis[port].pad.buttons.left)     ? (UINT64_C(1) << GX_SIXAXIS_LEFT) : 0;
         *state_cur |= (sixaxis[port].pad.buttons.right)    ? (UINT64_C(1) << GX_SIXAXIS_RIGHT) : 0;
         *state_cur |= (sixaxis[port].pad.buttons.circle)   ? (UINT64_C(1) << GX_SIXAXIS_CIRCLE) : 0;
         *state_cur |= (sixaxis[port].pad.buttons.triangle) ? (UINT64_C(1) << GX_SIXAXIS_TRIANGLE) : 0;
         *state_cur |= (sixaxis[port].pad.buttons.L1)       ? (UINT64_C(1) << GX_SIXAXIS_L1) : 0;
         *state_cur |= (sixaxis[port].pad.buttons.R1)       ? (UINT64_C(1) << GX_SIXAXIS_R1) : 0;
         *state_cur |= (sixaxis[port].pad.buttons.L2)       ? (UINT64_C(1) << GX_SIXAXIS_L2) : 0;
         *state_cur |= (sixaxis[port].pad.buttons.R2)       ? (UINT64_C(1) << GX_SIXAXIS_R2) : 0;
         *state_cur |= (sixaxis[port].pad.buttons.L3)       ? (UINT64_C(1) << GX_SIXAXIS_L3) : 0;
         *state_cur |= (sixaxis[port].pad.buttons.R3)       ? (UINT64_C(1) << GX_SIXAXIS_R3) : 0;

         ls_x = (int16_t)(sixaxis[port].pad.left_analog.x - 128) << 8;
         ls_y = (int16_t)(sixaxis[port].pad.left_analog.y - 128) << 8;
         rs_x = (int16_t)(sixaxis[port].pad.right_analog.x - 128) << 8;
         rs_y = (int16_t)(sixaxis[port].pad.right_analog.y - 128) << 8;

         analog_state[port][RETRO_DEVICE_INDEX_ANALOG_LEFT][RETRO_DEVICE_ID_ANALOG_X] = ls_x;
         analog_state[port][RETRO_DEVICE_INDEX_ANALOG_LEFT][RETRO_DEVICE_ID_ANALOG_Y] = ls_y;
         analog_state[port][RETRO_DEVICE_INDEX_ANALOG_RIGHT][RETRO_DEVICE_ID_ANALOG_X] = rs_x;
         analog_state[port][RETRO_DEVICE_INDEX_ANALOG_RIGHT][RETRO_DEVICE_ID_ANALOG_Y] = rs_y;

         ptype = WPAD_EXP_SICKSAXIS;
      }
#endif
      else if (WPADProbe(port, &ptype) == WPAD_ERR_NONE)
      {
         WPADData *wpaddata = (WPADData*)WPAD_Data(port);

         down = wpaddata->btns_h;

         *state_cur |= (down & WPAD_BUTTON_A) ? (UINT64_C(1) << GX_WIIMOTE_A) : 0;
         *state_cur |= (down & WPAD_BUTTON_B) ? (UINT64_C(1) << GX_WIIMOTE_B) : 0;
         *state_cur |= (down & WPAD_BUTTON_1) ? (UINT64_C(1) << GX_WIIMOTE_1) : 0;
         *state_cur |= (down & WPAD_BUTTON_2) ? (UINT64_C(1) << GX_WIIMOTE_2) : 0;
         *state_cur |= (down & WPAD_BUTTON_PLUS) ? (UINT64_C(1) << GX_WIIMOTE_PLUS) : 0;
         *state_cur |= (down & WPAD_BUTTON_MINUS) ? (UINT64_C(1) << GX_WIIMOTE_MINUS) : 0;
         *state_cur |= (down & WPAD_BUTTON_HOME) ? (UINT64_C(1) << GX_WIIMOTE_HOME) : 0;

         if (ptype != WPAD_EXP_NUNCHUK)
         {
            /* Rotated d-pad on Wiimote. */
            *state_cur |= (down & WPAD_BUTTON_UP) ? (UINT64_C(1) << GX_WIIMOTE_LEFT) : 0;
            *state_cur |= (down & WPAD_BUTTON_DOWN) ? (UINT64_C(1) << GX_WIIMOTE_RIGHT) : 0;
            *state_cur |= (down & WPAD_BUTTON_LEFT) ? (UINT64_C(1) << GX_WIIMOTE_DOWN) : 0;
            *state_cur |= (down & WPAD_BUTTON_RIGHT) ? (UINT64_C(1) << GX_WIIMOTE_UP) : 0;
         }

         if (ptype == WPAD_EXP_CLASSIC)
         {
            *state_cur |= (down & WPAD_CLASSIC_BUTTON_A) ? (UINT64_C(1) << GX_CLASSIC_A) : 0;
            *state_cur |= (down & WPAD_CLASSIC_BUTTON_B) ? (UINT64_C(1) << GX_CLASSIC_B) : 0;
            *state_cur |= (down & WPAD_CLASSIC_BUTTON_X) ? (UINT64_C(1) << GX_CLASSIC_X) : 0;
            *state_cur |= (down & WPAD_CLASSIC_BUTTON_Y) ? (UINT64_C(1) << GX_CLASSIC_Y) : 0;
            *state_cur |= (down & WPAD_CLASSIC_BUTTON_UP) ? (UINT64_C(1) << GX_CLASSIC_UP) : 0;
            *state_cur |= (down & WPAD_CLASSIC_BUTTON_DOWN) ? (UINT64_C(1) << GX_CLASSIC_DOWN) : 0;
            *state_cur |= (down & WPAD_CLASSIC_BUTTON_LEFT) ? (UINT64_C(1) << GX_CLASSIC_LEFT) : 0;
            *state_cur |= (down & WPAD_CLASSIC_BUTTON_RIGHT) ? (UINT64_C(1) << GX_CLASSIC_RIGHT) : 0;
            *state_cur |= (down & WPAD_CLASSIC_BUTTON_PLUS) ? (UINT64_C(1) << GX_CLASSIC_PLUS) : 0;
            *state_cur |= (down & WPAD_CLASSIC_BUTTON_MINUS) ? (UINT64_C(1) << GX_CLASSIC_MINUS) : 0;
            *state_cur |= (down & WPAD_CLASSIC_BUTTON_HOME) ? (UINT64_C(1) << GX_CLASSIC_HOME) : 0;
            *state_cur |= (down & WPAD_CLASSIC_BUTTON_FULL_L) ? (UINT64_C(1) << GX_CLASSIC_L_TRIGGER) : 0;
            *state_cur |= (down & WPAD_CLASSIC_BUTTON_FULL_R) ? (UINT64_C(1) << GX_CLASSIC_R_TRIGGER) : 0;
            *state_cur |= (down & WPAD_CLASSIC_BUTTON_ZL) ? (UINT64_C(1) << GX_CLASSIC_ZL_TRIGGER) : 0;
            *state_cur |= (down & WPAD_CLASSIC_BUTTON_ZR) ? (UINT64_C(1) << GX_CLASSIC_ZR_TRIGGER) : 0;

            analog_state[port][RETRO_DEVICE_INDEX_ANALOG_LEFT][RETRO_DEVICE_ID_ANALOG_X]  = WPAD_StickX(wpaddata, 0);
            analog_state[port][RETRO_DEVICE_INDEX_ANALOG_LEFT][RETRO_DEVICE_ID_ANALOG_Y]  = WPAD_StickY(wpaddata, 0);
            analog_state[port][RETRO_DEVICE_INDEX_ANALOG_RIGHT][RETRO_DEVICE_ID_ANALOG_X] = WPAD_StickX(wpaddata, 1);
            analog_state[port][RETRO_DEVICE_INDEX_ANALOG_RIGHT][RETRO_DEVICE_ID_ANALOG_Y] = WPAD_StickY(wpaddata, 1);
         }
         else if (ptype == WPAD_EXP_NUNCHUK)
         {
            /* Wiimote is held upright with nunchuk,
             * do not change d-pad orientation. */
            *state_cur |= (down & WPAD_BUTTON_UP) ? (UINT64_C(1) << GX_WIIMOTE_UP) : 0;
            *state_cur |= (down & WPAD_BUTTON_DOWN) ? (UINT64_C(1) << GX_WIIMOTE_DOWN) : 0;
            *state_cur |= (down & WPAD_BUTTON_LEFT) ? (UINT64_C(1) << GX_WIIMOTE_LEFT) : 0;
            *state_cur |= (down & WPAD_BUTTON_RIGHT) ? (UINT64_C(1) << GX_WIIMOTE_RIGHT) : 0;

            *state_cur |= (down & WPAD_NUNCHUK_BUTTON_Z) ? (UINT64_C(1) << GX_NUNCHUK_Z) : 0;
            *state_cur |= (down & WPAD_NUNCHUK_BUTTON_C) ? (UINT64_C(1) << GX_NUNCHUK_C) : 0;

            analog_state[port][RETRO_DEVICE_INDEX_ANALOG_LEFT][RETRO_DEVICE_ID_ANALOG_X] = WPAD_StickX(wpaddata, 0);
            analog_state[port][RETRO_DEVICE_INDEX_ANALOG_LEFT][RETRO_DEVICE_ID_ANALOG_Y] = WPAD_StickY(wpaddata, 0);
         }
      }
#endif

      if (ptype != pad_type[port])
         handle_hotplug(port, ptype);

      for (i = 0; i < 2; i++)
         for (j = 0; j < 2; j++)
            if (analog_state[port][i][j] == -0x8000)
               analog_state[port][i][j] = -0x7fff;
   }

   uint64_t *state_p1 = &pad_state[0];


   BIT64_CLEAR(lifecycle_state, RARCH_MENU_TOGGLE);
   if (g_menu)
   {
      *state_p1 |= (UINT64_C(1) << GX_GC_HOME);
      g_menu = false;
   }

   if (*state_p1 & ((UINT64_C(1) << GX_GC_HOME)
#ifdef HW_RVL
            | (UINT64_C(1) << GX_WIIMOTE_HOME)
            | (UINT64_C(1) << GX_CLASSIC_HOME)
#ifdef HAVE_LIBSICKSAXIS
            | (UINT64_C(1) << GX_SIXAXIS_PS)
#endif
#endif
            ))
    
   BIT64_SET(lifecycle_state, RARCH_MENU_TOGGLE);
}
Beispiel #14
0
static void iohidmanager_hid_device_input_callback(void *data, IOReturn result,
      void* sender, IOHIDValueRef value)
{
   iohidmanager_hid_t *hid                  = (iohidmanager_hid_t*)hid_driver_get_data();
   struct iohidmanager_hid_adapter *adapter = (struct iohidmanager_hid_adapter*)data;
   IOHIDElementRef element                  = IOHIDValueGetElement(value);
   uint32_t type                            = (uint32_t)IOHIDElementGetType(element);
   uint32_t page                            = (uint32_t)IOHIDElementGetUsagePage(element);
   uint32_t use                             = (uint32_t)IOHIDElementGetUsage(element);
   uint32_t cookie                          = (uint32_t)IOHIDElementGetCookie(element);
   apple_input_rec_t *tmp                   = NULL;

   if (type != kIOHIDElementTypeInput_Misc)
      if (type != kIOHIDElementTypeInput_Button)
         if (type != kIOHIDElementTypeInput_Axis)
            return;

   /* Joystick handler.
    * TODO: Can GamePad work the same? */

   int pushed_button = 0;

   switch (page)
   {
      case kHIDPage_GenericDesktop:
         switch (type)
         {
            case kIOHIDElementTypeInput_Misc:
               switch (use)
               {
                  case kHIDUsage_GD_Hatswitch:
                     {
                        tmp = adapter->hats;

                        while(tmp && tmp->cookie != (IOHIDElementCookie)cookie)
                           tmp = tmp->next;

                        if(tmp->cookie == (IOHIDElementCookie)cookie)
                        {
                           CFIndex range = IOHIDElementGetLogicalMax(element) - IOHIDElementGetLogicalMin(element);
                           CFIndex val   = IOHIDValueGetIntegerValue(value);

                           if(range == 3)
                              val *= 2;

                           switch(val)
                           {
                              case 0:
                                 /* pos = up */
                                 hid->hats[adapter->slot][0] = 0;
                                 hid->hats[adapter->slot][1] = -1;
                                 break;
                              case 1:
                                 /* pos = up+right */
                                 hid->hats[adapter->slot][0] = 1;
                                 hid->hats[adapter->slot][1] = -1;
                                 break;
                              case 2:
                                 /* pos = right */
                                 hid->hats[adapter->slot][0] = 1;
                                 hid->hats[adapter->slot][1] = 0;
                                 break;
                              case 3:
                                 /* pos = down+right */
                                 hid->hats[adapter->slot][0] = 1;
                                 hid->hats[adapter->slot][1] = 1;
                                 break;
                              case 4:
                                 /* pos = down */
                                 hid->hats[adapter->slot][0] = 0;
                                 hid->hats[adapter->slot][1] = 1;
                                 break;
                              case 5:
                                 /* pos = down+left */
                                 hid->hats[adapter->slot][0] = -1;
                                 hid->hats[adapter->slot][1] = 1;
                                 break;
                              case 6:
                                 /* pos = left */
                                 hid->hats[adapter->slot][0] = -1;
                                 hid->hats[adapter->slot][1] = 0;
                                 break;
                              case 7:
                                 /* pos = up_left */
                                 hid->hats[adapter->slot][0] = -1;
                                 hid->hats[adapter->slot][1] = -1;
                                 break;
                              default:
                                 /* pos = centered */
                                 hid->hats[adapter->slot][0] = 0;
                                 hid->hats[adapter->slot][1] = 0;
                                 break;
                           }
                        }
                     }
                     break;
                  default:
                     tmp = adapter->axes;

                     while(tmp && tmp->cookie != (IOHIDElementCookie)cookie)
                        tmp = tmp->next;

                     if (tmp)
                     {
                        if(tmp->cookie == (IOHIDElementCookie)cookie)
                        {
                           CFIndex min   = IOHIDElementGetPhysicalMin(element);
                           CFIndex state = IOHIDValueGetIntegerValue(value) - min;
                           CFIndex max   = IOHIDElementGetPhysicalMax(element) - min;
                           float val     = (float)state / (float)max;

                           hid->axes[adapter->slot][tmp->id] =
                              ((val * 2.0f) - 1.0f) * 32767.0f;
                        }
                     }
                     else
                        pushed_button = 1;
                     break;
               }
               break;
         }
         break;
      case kHIDPage_Consumer:
      case kHIDPage_Button:
         switch (type)
         {
            case kIOHIDElementTypeInput_Misc:
            case kIOHIDElementTypeInput_Button:
               pushed_button = 1;
               break;
         }
         break;
   }

   if (pushed_button)
   {
      tmp = adapter->buttons;

      uint8_t bit = 0;
      while(tmp && tmp->cookie != (IOHIDElementCookie)cookie)
      {
         bit++;
         tmp = tmp->next;
      }

      if(tmp && tmp->cookie == (IOHIDElementCookie)cookie)
      {
         CFIndex state = IOHIDValueGetIntegerValue(value);
         if (state)
            BIT64_SET(hid->buttons[adapter->slot], bit);
         else
            BIT64_CLEAR(hid->buttons[adapter->slot], bit);
      }
   }
}
Beispiel #15
0
bool menu_driver_ctl(enum rarch_menu_ctl_state state, void *data)
{
   static struct retro_system_info menu_driver_system;
   static bool menu_driver_pending_quick_menu      = false;
   static bool menu_driver_pending_action          = false;
   static bool menu_driver_prevent_populate        = false;
   static bool menu_driver_load_no_content         = false;
   static bool menu_driver_alive                   = false;
   static bool menu_driver_data_own                = false;
   static bool menu_driver_pending_quit            = false;
   static bool menu_driver_pending_shutdown        = false;
   static playlist_t *menu_driver_playlist = NULL;
   static struct video_shader *menu_driver_shader  = NULL;
   static menu_handle_t *menu_driver_data          = NULL;
   static const menu_ctx_driver_t *menu_driver_ctx = NULL;
   static void *menu_userdata                      = NULL;
   settings_t *settings                            = config_get_ptr();

   switch (state)
   {
      case RARCH_MENU_CTL_IS_PENDING_ACTION:
         if (!menu_driver_pending_action)
            return false;
         menu_driver_ctl(RARCH_MENU_CTL_UNSET_PENDING_ACTION, NULL);
         break;
      case RARCH_MENU_CTL_SET_PENDING_ACTION:
         menu_driver_pending_action = true;
         break;
      case RARCH_MENU_CTL_UNSET_PENDING_ACTION:
         menu_driver_pending_action = false;
         break;
      case RARCH_MENU_CTL_DRIVER_DATA_GET:
         {
            menu_handle_t **driver_data = (menu_handle_t**)data;
            if (!driver_data)
               return false;
            *driver_data = menu_driver_data;
         }
         break;
      case RARCH_MENU_CTL_IS_PENDING_QUICK_MENU:
         return menu_driver_pending_quick_menu;
      case RARCH_MENU_CTL_SET_PENDING_QUICK_MENU:
         menu_driver_pending_quick_menu = true;
         break;
      case RARCH_MENU_CTL_UNSET_PENDING_QUICK_MENU:
         menu_driver_pending_quick_menu = false;
         break;
      case RARCH_MENU_CTL_IS_PENDING_QUIT:
         return menu_driver_pending_quit;
      case RARCH_MENU_CTL_SET_PENDING_QUIT:
         menu_driver_pending_quit     = true;
         break;
      case RARCH_MENU_CTL_UNSET_PENDING_QUIT:
         menu_driver_pending_quit     = false;
         break;
      case RARCH_MENU_CTL_IS_PENDING_SHUTDOWN:
         return menu_driver_pending_shutdown;
      case RARCH_MENU_CTL_SET_PENDING_SHUTDOWN:
         menu_driver_pending_shutdown = true;
         break;
      case RARCH_MENU_CTL_UNSET_PENDING_SHUTDOWN:
         menu_driver_pending_shutdown = false;
         break;
      case RARCH_MENU_CTL_DESTROY:
         menu_driver_pending_quick_menu = false;
         menu_driver_pending_action     = false;
         menu_driver_pending_quit       = false;
         menu_driver_pending_shutdown   = false;
         menu_driver_prevent_populate   = false;
         menu_driver_load_no_content    = false;
         menu_driver_alive              = false;
         menu_driver_data_own           = false;
         menu_driver_ctx                = NULL;
         menu_userdata                  = NULL;
         break;
      case RARCH_MENU_CTL_PLAYLIST_FREE:
         if (menu_driver_playlist)
            playlist_free(menu_driver_playlist);
         menu_driver_playlist = NULL;
         break;
      case RARCH_MENU_CTL_FIND_DRIVER:
         {
            int i;
            driver_ctx_info_t drv;
            settings_t *settings = config_get_ptr();

            drv.label = "menu_driver";
            drv.s     = settings->menu.driver;

            driver_ctl(RARCH_DRIVER_CTL_FIND_INDEX, &drv);

            i = drv.len;

            if (i >= 0)
               menu_driver_ctx = (const menu_ctx_driver_t*)
                  menu_driver_find_handle(i);
            else
            {
               unsigned d;
               RARCH_WARN("Couldn't find any menu driver named \"%s\"\n",
                     settings->menu.driver);
               RARCH_LOG_OUTPUT("Available menu drivers are:\n");
               for (d = 0; menu_driver_find_handle(d); d++)
                  RARCH_LOG_OUTPUT("\t%s\n", menu_driver_find_ident(d));
               RARCH_WARN("Going to default to first menu driver...\n");

               menu_driver_ctx = (const menu_ctx_driver_t*)
                  menu_driver_find_handle(0);

               if (!menu_driver_ctx)
               {
                  retroarch_fail(1, "find_menu_driver()");
                  return false;
               }
            }
         }
         break;
      case RARCH_MENU_CTL_PLAYLIST_INIT:
         {
            const char *path = (const char*)data;
            if (string_is_empty(path))
               return false;
            menu_driver_playlist  = playlist_init(path,
                  COLLECTION_SIZE);
         }
         break;
      case RARCH_MENU_CTL_PLAYLIST_GET:
         {
            playlist_t **playlist = (playlist_t**)data;
            if (!playlist)
               return false;
            *playlist = menu_driver_playlist;
         }
         break;
      case RARCH_MENU_CTL_SYSTEM_INFO_GET:
         {
            struct retro_system_info **system = 
               (struct retro_system_info**)data;
            if (!system)
               return false;
            *system = &menu_driver_system;
         }
         break;
      case RARCH_MENU_CTL_SYSTEM_INFO_DEINIT:
         libretro_free_system_info(&menu_driver_system);
         memset(&menu_driver_system, 0, sizeof(struct retro_system_info));
         break;
      case RARCH_MENU_CTL_RENDER_MESSAGEBOX:
         if (menu_driver_ctx->render_messagebox)
            menu_driver_ctx->render_messagebox(menu_userdata,
                  menu_driver_data->menu_state.msg);
         break;
      case RARCH_MENU_CTL_BLIT_RENDER:
         if (menu_driver_ctx->render)
            menu_driver_ctx->render(menu_userdata);
         break;
      case RARCH_MENU_CTL_RENDER:
         if (!menu_driver_data)
            return false;

         if (BIT64_GET(menu_driver_data->state, MENU_STATE_RENDER_FRAMEBUFFER) 
               != BIT64_GET(menu_driver_data->state, MENU_STATE_RENDER_MESSAGEBOX))
            BIT64_SET(menu_driver_data->state, MENU_STATE_RENDER_FRAMEBUFFER);

         if (BIT64_GET(menu_driver_data->state, MENU_STATE_RENDER_FRAMEBUFFER))
            menu_display_set_framebuffer_dirty_flag();

         if (BIT64_GET(menu_driver_data->state, MENU_STATE_RENDER_MESSAGEBOX) 
               && !string_is_empty(menu_driver_data->menu_state.msg))
         {
            menu_driver_ctl(RARCH_MENU_CTL_RENDER_MESSAGEBOX, NULL);

            if (ui_companion_is_on_foreground())
            {
               const ui_companion_driver_t *ui = ui_companion_get_ptr();
               if (ui->render_messagebox)
                  ui->render_messagebox(menu_driver_data->menu_state.msg);
            }
         }

         if (BIT64_GET(menu_driver_data->state, MENU_STATE_BLIT))
         {
            menu_animation_ctl(MENU_ANIMATION_CTL_UPDATE_TIME, NULL);
            menu_driver_ctl(RARCH_MENU_CTL_BLIT_RENDER, NULL);
         }

         if (menu_driver_ctl(RARCH_MENU_CTL_IS_ALIVE, NULL) 
               && !runloop_ctl(RUNLOOP_CTL_IS_IDLE, NULL))
            menu_display_libretro();

         menu_driver_ctl(RARCH_MENU_CTL_SET_TEXTURE, NULL);

         menu_driver_data->state               = 0;
         break;
      case RARCH_MENU_CTL_SHADER_DEINIT:
#ifdef HAVE_SHADER_MANAGER
         if (menu_driver_shader)
            free(menu_driver_shader);
         menu_driver_shader = NULL;
#endif
         break;
      case RARCH_MENU_CTL_SHADER_INIT:
#ifdef HAVE_SHADER_MANAGER
         menu_driver_shader = (struct video_shader*)
            calloc(1, sizeof(struct video_shader));
         if (!menu_driver_shader)
            return false;
#endif
         break;
      case RARCH_MENU_CTL_SHADER_GET:
         {
            struct video_shader **shader = (struct video_shader**)data;
            if (!shader)
               return false;
            *shader = menu_driver_shader;
         }
         break;
      case RARCH_MENU_CTL_FRAME:
         if (!menu_driver_alive)
            return false;
         if (menu_driver_ctx->frame)
            menu_driver_ctx->frame(menu_userdata);
         break;
      case RARCH_MENU_CTL_SET_PREVENT_POPULATE:
         menu_driver_prevent_populate = true;
         break;
      case RARCH_MENU_CTL_UNSET_PREVENT_POPULATE:
         menu_driver_prevent_populate = false;
         break;
      case RARCH_MENU_CTL_IS_PREVENT_POPULATE:
         return menu_driver_prevent_populate;
      case RARCH_MENU_CTL_SET_TOGGLE:
         menu_driver_toggle(true);
         break;
      case RARCH_MENU_CTL_UNSET_TOGGLE:
         menu_driver_toggle(false);
         break;
      case RARCH_MENU_CTL_SET_ALIVE:
         menu_driver_alive = true;
         break;
      case RARCH_MENU_CTL_UNSET_ALIVE:
         menu_driver_alive = false;
         break;
      case RARCH_MENU_CTL_IS_ALIVE:
         return menu_driver_alive;
      case RARCH_MENU_CTL_SET_OWN_DRIVER:
         menu_driver_data_own = true;
         break;
      case RARCH_MENU_CTL_UNSET_OWN_DRIVER:
         if (!content_is_inited())
            return false;
         menu_driver_data_own = false;
         break;
      case RARCH_MENU_CTL_SET_TEXTURE:
         if (menu_driver_ctx->set_texture)
            menu_driver_ctx->set_texture();
         break;
      case RARCH_MENU_CTL_IS_SET_TEXTURE:
         if (!menu_driver_ctx)
            return false;
         return menu_driver_ctx->set_texture;
      case RARCH_MENU_CTL_OWNS_DRIVER:
         return menu_driver_data_own;
      case RARCH_MENU_CTL_DEINIT:
         menu_driver_ctl(RARCH_MENU_CTL_CONTEXT_DESTROY, NULL);
         if (menu_driver_ctl(RARCH_MENU_CTL_OWNS_DRIVER, NULL))
            return true;
         if (menu_driver_data)
         {
            menu_driver_ctl(RARCH_MENU_CTL_PLAYLIST_FREE, NULL);
            menu_shader_free(menu_driver_data);
            menu_input_ctl(MENU_INPUT_CTL_DEINIT, NULL);
            menu_navigation_ctl(MENU_NAVIGATION_CTL_DEINIT, NULL);

            if (menu_driver_ctx && menu_driver_ctx->free)
               menu_driver_ctx->free(menu_userdata);

            if (menu_userdata)
               free(menu_userdata);
            menu_userdata = NULL;

            menu_driver_ctl(RARCH_MENU_CTL_SYSTEM_INFO_DEINIT, NULL);
            menu_display_deinit();
            menu_entries_ctl(MENU_ENTRIES_CTL_DEINIT, NULL);

            command_event(CMD_EVENT_HISTORY_DEINIT, NULL);

            core_info_deinit_list();
            core_info_free_current_core();

            free(menu_driver_data);
         }
         menu_driver_data = NULL;
         break;
      case RARCH_MENU_CTL_INIT:
         if (menu_driver_data)
            return true;

         menu_driver_data = (menu_handle_t*)
            menu_driver_ctx->init(&menu_userdata);

         if (!menu_driver_data || !menu_init(menu_driver_data))
         {
            retroarch_fail(1, "init_menu()");
            return false;
         }

         strlcpy(settings->menu.driver, menu_driver_ctx->ident,
               sizeof(settings->menu.driver));

         if (menu_driver_ctx->lists_init)
         {
            if (!menu_driver_ctx->lists_init(menu_driver_data))
            {
               retroarch_fail(1, "init_menu()");
               return false;
            }
         }
         break;
      case RARCH_MENU_CTL_LOAD_NO_CONTENT_GET:
         {
            bool **ptr = (bool**)data;
            if (!ptr)
               return false;
            *ptr = (bool*)&menu_driver_load_no_content;
         }
         break;
      case RARCH_MENU_CTL_HAS_LOAD_NO_CONTENT:
         return menu_driver_load_no_content;
      case RARCH_MENU_CTL_SET_LOAD_NO_CONTENT:
         menu_driver_load_no_content = true;
         break;
      case RARCH_MENU_CTL_UNSET_LOAD_NO_CONTENT:
         menu_driver_load_no_content = false;
         break;
      case RARCH_MENU_CTL_NAVIGATION_INCREMENT:
         if (menu_driver_ctx->navigation_increment)
            menu_driver_ctx->navigation_increment(menu_userdata);
         break;
      case RARCH_MENU_CTL_NAVIGATION_DECREMENT:
         if (menu_driver_ctx->navigation_decrement)
            menu_driver_ctx->navigation_decrement(menu_userdata);
         break;
      case RARCH_MENU_CTL_NAVIGATION_SET:
         {
            bool *scroll = (bool*)data;

            if (!scroll)
               return false;
            if (menu_driver_ctx->navigation_set)
               menu_driver_ctx->navigation_set(menu_userdata, *scroll);
         }
         break;
      case RARCH_MENU_CTL_NAVIGATION_SET_LAST:
         if (menu_driver_ctx->navigation_set_last)
            menu_driver_ctx->navigation_set_last(menu_userdata);
         break;
      case RARCH_MENU_CTL_NAVIGATION_ASCEND_ALPHABET:
         {
            size_t *ptr_out = (size_t*)data;

            if (!ptr_out)
               return false;

            if (menu_driver_ctx->navigation_ascend_alphabet)
               menu_driver_ctx->navigation_ascend_alphabet(
                     menu_userdata, ptr_out);
         }
      case RARCH_MENU_CTL_NAVIGATION_DESCEND_ALPHABET:
         {
            size_t *ptr_out = (size_t*)data;

            if (!ptr_out)
               return false;

            if (menu_driver_ctx->navigation_descend_alphabet)
               menu_driver_ctx->navigation_descend_alphabet(
                     menu_userdata, ptr_out);
         }
         break;
      case RARCH_MENU_CTL_NAVIGATION_CLEAR:
         {
            bool *pending_push = (bool*)data;

            if (!pending_push)
               return false;
            if (menu_driver_ctx->navigation_clear)
               menu_driver_ctx->navigation_clear(
                     menu_userdata, pending_push);
         }
         break;
      case RARCH_MENU_CTL_POPULATE_ENTRIES:
         {
            menu_displaylist_info_t *info = (menu_displaylist_info_t*)data;

            if (!info)
               return false;
            if (menu_driver_ctx->populate_entries)
               menu_driver_ctx->populate_entries(
                     menu_userdata, info->path,
                     info->label, info->type);
         }
         break;
      case RARCH_MENU_CTL_LIST_GET_ENTRY:
         {
            menu_ctx_list_t *list = (menu_ctx_list_t*)data;

            if (!menu_driver_ctx || !menu_driver_ctx->list_get_entry)
            {
               list->entry = NULL;
               return false;
            }
            list->entry = menu_driver_ctx->list_get_entry(menu_userdata,
                  list->type, list->idx);
         }
         break;
      case RARCH_MENU_CTL_LIST_GET_SIZE:
         {
            menu_ctx_list_t *list = (menu_ctx_list_t*)data;
            if (!menu_driver_ctx || !menu_driver_ctx->list_get_size)
            {
               list->size = 0;
               return false;
            }
            list->size = menu_driver_ctx->list_get_size(menu_userdata, list->type);
         }
         break;
      case RARCH_MENU_CTL_LIST_GET_SELECTION:
         {
            menu_ctx_list_t *list = (menu_ctx_list_t*)data;

            if (!menu_driver_ctx || !menu_driver_ctx->list_get_selection)
            {
               list->selection = 0;
               return false;
            }
            list->selection = menu_driver_ctx->list_get_selection(menu_userdata);
         }
         break;
      case RARCH_MENU_CTL_LIST_FREE:
         {
            menu_ctx_list_t *list = (menu_ctx_list_t*)data;

            if (menu_driver_ctx)
            {
               if (menu_driver_ctx->list_free)
                  menu_driver_ctx->list_free(list->list, list->idx, list->list_size);
            }

            if (list->list)
            {
               file_list_free_userdata  (list->list, list->idx);
               file_list_free_actiondata(list->list, list->idx);
            }
         }
         break;
      case RARCH_MENU_CTL_LIST_PUSH:
         {
            menu_ctx_displaylist_t *disp_list = (menu_ctx_displaylist_t*)data;

            if (menu_driver_ctx->list_push)
               if (menu_driver_ctx->list_push(menu_driver_data,
                        menu_userdata, disp_list->info, disp_list->type) == 0)
                  return true;
         }
         return false;
      case RARCH_MENU_CTL_LIST_CLEAR:
         {
            file_list_t *list = (file_list_t*)data;
            if (!list)
               return false;
            if (menu_driver_ctx->list_clear)
               menu_driver_ctx->list_clear(list);
         }
         break;
      case RARCH_MENU_CTL_TOGGLE:
         {
            bool *latch = (bool*)data;
            if (!latch)
               return false;

            if (menu_driver_ctx && menu_driver_ctx->toggle)
               menu_driver_ctx->toggle(menu_userdata, *latch);
         }
         break;
      case RARCH_MENU_CTL_REFRESH:
         {
#if 0
            bool refresh = false;
            menu_entries_ctl(MENU_ENTRIES_CTL_LIST_DEINIT, NULL);
            menu_entries_ctl(MENU_ENTRIES_CTL_SETTINGS_DEINIT, NULL);
            menu_entries_ctl(MENU_ENTRIES_CTL_INIT, NULL);
            menu_entries_ctl(MENU_ENTRIES_CTL_SET_REFRESH, &refresh);
#endif
         }
         break;
      case RARCH_MENU_CTL_CONTEXT_RESET:
         if (!menu_driver_ctx || !menu_driver_ctx->context_reset)
            return false;
         menu_driver_ctx->context_reset(menu_userdata);
         break;
      case RARCH_MENU_CTL_CONTEXT_DESTROY:
         if (!menu_driver_ctx || !menu_driver_ctx->context_destroy)
            return false;
         menu_driver_ctx->context_destroy(menu_userdata);
         break;
      case RARCH_MENU_CTL_SHADER_MANAGER_INIT:
         menu_shader_manager_init(menu_driver_data);
         break;
      case RARCH_MENU_CTL_LIST_SET_SELECTION:
         {
            file_list_t *list = (file_list_t*)data;

            if (!list)
               return false;

            if (!menu_driver_ctx || !menu_driver_ctx->list_set_selection)
               return false;

            menu_driver_ctx->list_set_selection(menu_userdata, list);
         }
         break;
      case RARCH_MENU_CTL_LIST_CACHE:
         {
            menu_ctx_list_t *list = (menu_ctx_list_t*)data;
            if (!list || !menu_driver_ctx || !menu_driver_ctx->list_cache)
               return false;
            menu_driver_ctx->list_cache(menu_userdata,
                  list->type, list->action);
         }
         break;
      case RARCH_MENU_CTL_LIST_INSERT:
         {
            menu_ctx_list_t *list = (menu_ctx_list_t*)data;
            if (!list || !menu_driver_ctx || !menu_driver_ctx->list_insert)
               return false;
            menu_driver_ctx->list_insert(menu_userdata,
                  list->list, list->path, list->label, list->idx);
         }
         break;
      case RARCH_MENU_CTL_LOAD_IMAGE:
         {
            menu_ctx_load_image_t *load_image_info = 
               (menu_ctx_load_image_t*)data;
            if (!menu_driver_ctx || !menu_driver_ctx->load_image)
               return false;
            return menu_driver_ctx->load_image(menu_userdata,
                  load_image_info->data, load_image_info->type);
         }
      case RARCH_MENU_CTL_ITERATE:
         {
            bool retcode = false;
            menu_ctx_iterate_t *iterate = (menu_ctx_iterate_t*)data;

            if (menu_driver_ctl(RARCH_MENU_CTL_IS_PENDING_QUICK_MENU, NULL))
            {
               menu_driver_ctl(RARCH_MENU_CTL_UNSET_PENDING_QUICK_MENU, NULL);
               menu_entries_flush_stack(NULL, MENU_SETTINGS);
               menu_display_set_msg_force(true);

               generic_action_ok_displaylist_push("",
                     "", 0, 0, 0, ACTION_OK_DL_CONTENT_SETTINGS);

               if (menu_driver_ctl(RARCH_MENU_CTL_IS_PENDING_QUIT, NULL))
               {
                  menu_driver_ctl(RARCH_MENU_CTL_UNSET_PENDING_QUIT, NULL);
                  return false;
               }

               return true;
            }

            if (menu_driver_ctl(RARCH_MENU_CTL_IS_PENDING_QUIT, NULL))
            {
               menu_driver_ctl(RARCH_MENU_CTL_UNSET_PENDING_QUIT, NULL);
               return false;
            }
            if (menu_driver_ctl(RARCH_MENU_CTL_IS_PENDING_SHUTDOWN, NULL))
            {
               menu_driver_ctl(RARCH_MENU_CTL_UNSET_PENDING_SHUTDOWN, NULL);
               if (!command_event(CMD_EVENT_QUIT, NULL))
                  return false;
               return true;
            }
            if (!menu_driver_ctx || !menu_driver_ctx->iterate)
               return false;
             
            if (menu_driver_ctl(RARCH_MENU_CTL_IS_PENDING_ACTION, &retcode))
            {
                iterate->action = pending_iter.action;
                pending_iter.action = MENU_ACTION_NOOP;
            }
            if (menu_driver_ctx->iterate(menu_driver_data,
                     menu_userdata, iterate->action) == -1)
               return false;
         }
         break;
      case RARCH_MENU_CTL_ENVIRONMENT:
         {
            menu_ctx_environment_t *menu_environ = 
               (menu_ctx_environment_t*)data;

            if (menu_driver_ctx->environ_cb)
            {
               if (menu_driver_ctx->environ_cb(menu_environ->type,
                        menu_environ->data, menu_userdata) == 0)
                  return true;
            }
         }
         return false;
      case RARCH_MENU_CTL_POINTER_TAP:
         {
            menu_ctx_pointer_t *point = (menu_ctx_pointer_t*)data;
            if (!menu_driver_ctx || !menu_driver_ctx->pointer_tap)
            {
               point->retcode = 0;
               return false;
            }
            point->retcode = menu_driver_ctx->pointer_tap(menu_userdata,
                  point->x, point->y, point->ptr,
                  point->cbs, point->entry, point->action);
         }
         break;
      case RARCH_MENU_CTL_BIND_INIT:
         {
            menu_ctx_bind_t *bind = (menu_ctx_bind_t*)data;

            if (!menu_driver_ctx || !menu_driver_ctx->bind_init)
            {
               bind->retcode = 0;
               return false;
            }
            bind->retcode = menu_driver_ctx->bind_init(
                  bind->cbs,
                  bind->path,
                  bind->label,
                  bind->type,
                  bind->idx,
                  bind->elem0,
                  bind->elem1,
                  bind->label_hash,
                  bind->menu_label_hash);
         }
         break;
      case RARCH_MENU_CTL_UPDATE_THUMBNAIL_PATH:
         {
            size_t selection;
            if (!menu_navigation_ctl(MENU_NAVIGATION_CTL_GET_SELECTION, &selection))
               return false;

            if (!menu_driver_ctx || !menu_driver_ctx->update_thumbnail_path)
               return false;
            menu_driver_ctx->update_thumbnail_path(menu_userdata, selection);
         }
         break;
      case RARCH_MENU_CTL_UPDATE_THUMBNAIL_IMAGE:
         {
            if (!menu_driver_ctx || !menu_driver_ctx->update_thumbnail_image)
               return false;
            menu_driver_ctx->update_thumbnail_image(menu_userdata);
         }
         break;
      default:
      case RARCH_MENU_CTL_NONE:
         break;
   }

   return true;
}
Beispiel #16
0
/**
 * rarch_main_iterate:
 *
 * Run Libretro core in RetroArch for one frame.
 *
 * Returns: 0 on success, 1 if we have to wait until button input in order
 * to wake up the loop, -1 if we forcibly quit out of the RetroArch iteration loop. 
 **/
int rarch_main_iterate(unsigned *sleep_ms)
{
   unsigned i;
   retro_input_t trigger_input;
   event_cmd_state_t    cmd;
   bool do_quit                    = false;
   static retro_input_t last_input = 0;
   driver_t *driver                = driver_get_ptr();
   settings_t *settings            = config_get_ptr();
   global_t   *global              = global_get_ptr();
   retro_input_t input             = input_keys_pressed(driver, settings, global);
   rarch_system_info_t *system     = rarch_system_info_get_ptr();
   retro_input_t old_input         = last_input;

   last_input                      = input;

   if (driver->flushing_input)
   {
      driver->flushing_input = false;
      if (input)
      {
         input = 0;

         /* If core was paused before entering menu, evoke
          * pause toggle to wake it up. */
         if (main_is_paused)
            BIT64_SET(input, RARCH_PAUSE_TOGGLE);
         driver->flushing_input = true;
      }
   }

   trigger_input = input & ~old_input;

   rarch_main_cmd_get_state(driver, settings, &cmd, input, old_input, trigger_input);

   if (time_to_exit(driver, global, system, &cmd))
      do_quit = true;

   if (system->frame_time.callback)
      rarch_update_frame_time(driver, settings->slowmotion_ratio, system);

   do_pre_state_checks(settings, global, &cmd);

#ifdef HAVE_OVERLAY
   rarch_main_iterate_linefeed_overlay(driver, settings);
#endif

   if (global->exec)
   {
      global->exec = false;
      do_quit      = true;
   }

   if (do_quit)
   {
      /* Quits out of RetroArch main loop.
       * On special case, loads dummy core 
       * instead of exiting RetroArch completely.
       * Aborts core shutdown if invoked.
       */
      if (global->core_shutdown_initiated
            && settings->load_dummy_on_core_shutdown)
      {
         if (!event_command(EVENT_CMD_PREPARE_DUMMY))
            return -1;

         system->shutdown = false;
         global->core_shutdown_initiated = false;

         return 0;
      }

      return -1;
   }
   
#ifdef HAVE_MENU
   if (menu_driver_alive())
   {
      menu_handle_t *menu = menu_driver_get_ptr();
      if (menu)
         if (menu_iterate(true, menu_input_frame(input, trigger_input)) == -1)
            rarch_main_set_state(RARCH_ACTION_STATE_MENU_RUNNING_FINISHED);

      if (!input && settings->menu.pause_libretro)
        return 1;
      return rarch_limit_frame_time(settings->fastforward_ratio, sleep_ms);
   }
#endif

   if (do_state_checks(driver, settings, global, &cmd))
   {
      /* RetroArch has been paused. */
      driver->retro_ctx.poll_cb();
      *sleep_ms = 10;
      return 1;
   }

#if defined(HAVE_THREADS)
   lock_autosave();
#endif

#ifdef HAVE_NETPLAY
   if (driver->netplay_data)
      netplay_pre_frame((netplay_t*)driver->netplay_data);
#endif

   if (global->bsv.movie)
      bsv_movie_set_frame_start(global->bsv.movie);

   if (system->camera_callback.caps)
      driver_camera_poll();

   /* Update binds for analog dpad modes. */
   for (i = 0; i < settings->input.max_users; i++)
   {
      if (!settings->input.analog_dpad_mode[i])
         continue;

      input_push_analog_dpad(settings->input.binds[i],
            settings->input.analog_dpad_mode[i]);
      input_push_analog_dpad(settings->input.autoconf_binds[i],
            settings->input.analog_dpad_mode[i]);
   }

   if ((settings->video.frame_delay > 0) && !driver->nonblock_state)
      rarch_sleep(settings->video.frame_delay);

   /* Run libretro for one frame. */
   pretro_run();

   for (i = 0; i < settings->input.max_users; i++)
   {
      if (!settings->input.analog_dpad_mode[i])
         continue;

      input_pop_analog_dpad(settings->input.binds[i]);
      input_pop_analog_dpad(settings->input.autoconf_binds[i]);
   }

   if (global->bsv.movie)
      bsv_movie_set_frame_end(global->bsv.movie);

#ifdef HAVE_NETPLAY
   if (driver->netplay_data)
      netplay_post_frame((netplay_t*)driver->netplay_data);
#endif

#if defined(HAVE_THREADS)
   unlock_autosave();
#endif

   return rarch_limit_frame_time(settings->fastforward_ratio, sleep_ms);
}
Beispiel #17
0
/**
 * runloop_iterate:
 *
 * Run Libretro core in RetroArch for one frame.
 *
 * Returns: 0 on success, 1 if we have to wait until 
 * button input in order to wake up the loop, 
 * -1 if we forcibly quit out of the RetroArch iteration loop.
 **/
int runloop_iterate(unsigned *sleep_ms)
{
   unsigned i;
   event_cmd_state_t    cmd;
   retro_time_t current, target, to_sleep_ms;
   static retro_input_t last_input              = {0};
   event_cmd_state_t   *cmd_ptr                 = &cmd;
   static retro_time_t frame_limit_minimum_time = 0.0;
   static retro_time_t frame_limit_last_time    = 0.0;
   settings_t *settings                         = config_get_ptr();

   cmd.state[1]                                 = last_input;
   cmd.state[0]                                 = input_keys_pressed();
   last_input                                   = cmd.state[0];

   runloop_ctl(RUNLOOP_CTL_UNSET_FRAME_TIME_LAST, NULL);

   if (runloop_ctl(RUNLOOP_CTL_SHOULD_SET_FRAME_LIMIT, NULL))
   {
      struct retro_system_av_info *av_info = 
         video_viewport_get_system_av_info();
      float fastforward_ratio              = 
         (settings->fastforward_ratio == 0.0f) 
         ? 1.0f : settings->fastforward_ratio;

      frame_limit_last_time    = cpu_features_get_time_usec();
      frame_limit_minimum_time = (retro_time_t)roundf(1000000.0f 
            / (av_info->timing.fps * fastforward_ratio));

      runloop_ctl(RUNLOOP_CTL_UNSET_FRAME_LIMIT, NULL);
   }

   if (input_driver_is_flushing_input())
   {
      input_driver_unset_flushing_input();
      if (cmd.state[0].state)
      {
         cmd.state[0].state = 0;

         /* If core was paused before entering menu, evoke
          * pause toggle to wake it up. */
         if (runloop_ctl(RUNLOOP_CTL_IS_PAUSED, NULL))
            BIT64_SET(cmd.state[0].state, RARCH_PAUSE_TOGGLE);
         input_driver_set_flushing_input();
      }
   }
   
   if (runloop_frame_time.callback)
   {
      /* Updates frame timing if frame timing callback is in use by the core.
       * Limits frame time if fast forward ratio throttle is enabled. */

      retro_time_t current     = cpu_features_get_time_usec();
      retro_time_t delta       = current - runloop_frame_time_last;
      bool is_locked_fps       = (runloop_ctl(RUNLOOP_CTL_IS_PAUSED, NULL) ||
                                  input_driver_is_nonblock_state()) |
                                  !!recording_driver_get_data_ptr();


      if (!runloop_frame_time_last || is_locked_fps)
         delta = runloop_frame_time.reference;

      if (!is_locked_fps && runloop_ctl(RUNLOOP_CTL_IS_SLOWMOTION, NULL))
         delta /= settings->slowmotion_ratio;

      runloop_frame_time_last = current;

      if (is_locked_fps)
         runloop_frame_time_last = 0;

      runloop_frame_time.callback(delta);
   }

   cmd.state[2].state      = cmd.state[0].state & ~cmd.state[1].state;  /* trigger  */

   if (runloop_cmd_triggered(cmd_ptr, RARCH_OVERLAY_NEXT))
      command_event(CMD_EVENT_OVERLAY_NEXT, NULL);

   if (runloop_cmd_triggered(cmd_ptr, RARCH_FULLSCREEN_TOGGLE_KEY))
   {
      bool fullscreen_toggled = !runloop_ctl(RUNLOOP_CTL_IS_PAUSED, NULL);
#ifdef HAVE_MENU
      fullscreen_toggled = fullscreen_toggled || 
         menu_driver_ctl(RARCH_MENU_CTL_IS_ALIVE, NULL);
#endif

      if (fullscreen_toggled)
         command_event(CMD_EVENT_FULLSCREEN_TOGGLE, NULL);
   }

   if (runloop_cmd_triggered(cmd_ptr, RARCH_GRAB_MOUSE_TOGGLE))
      command_event(CMD_EVENT_GRAB_MOUSE_TOGGLE, NULL);

#ifdef HAVE_MENU
   if (runloop_cmd_menu_press(cmd_ptr) || 
         rarch_ctl(RARCH_CTL_IS_DUMMY_CORE, NULL))
   {
      if (menu_driver_ctl(RARCH_MENU_CTL_IS_ALIVE, NULL))
      {
         if (rarch_ctl(RARCH_CTL_IS_INITED, NULL) && 
               !rarch_ctl(RARCH_CTL_IS_DUMMY_CORE, NULL))
            rarch_ctl(RARCH_CTL_MENU_RUNNING_FINISHED, NULL);
      }
      else
         rarch_ctl(RARCH_CTL_MENU_RUNNING, NULL);
   }
#endif

#ifdef HAVE_OVERLAY
   runloop_iterate_linefeed_overlay(settings);
#endif

   if (runloop_iterate_time_to_exit(
            runloop_cmd_press(cmd_ptr, RARCH_QUIT_KEY)) != 1)
   {
      frame_limit_last_time = 0.0;
      return -1;
   }


#ifdef HAVE_MENU
   if (menu_driver_ctl(RARCH_MENU_CTL_IS_ALIVE, NULL))
   {
      int ret = runloop_iterate_menu((enum menu_action)
      menu_input_frame_retropad(cmd.state[0], cmd.state[2]),
      sleep_ms);

      if (ret == -1)
         goto end;
      return ret;
   }
#endif

   if (!runloop_check_state(&cmd, &runloop_shader_dir))
   {
      /* RetroArch has been paused. */
      core_poll();
      *sleep_ms = 10;
      return 1;
   }

#if defined(HAVE_THREADS)
   autosave_lock();
#endif

#ifdef HAVE_NETPLAY
   netplay_driver_ctl(RARCH_NETPLAY_CTL_PRE_FRAME, NULL);
#endif

   if (bsv_movie_ctl(BSV_MOVIE_CTL_IS_INITED, NULL))
      bsv_movie_ctl(BSV_MOVIE_CTL_SET_FRAME_START, NULL);

   camera_driver_ctl(RARCH_CAMERA_CTL_POLL, NULL);

   /* Update binds for analog dpad modes. */
   for (i = 0; i < settings->input.max_users; i++)
   {
      if (!settings->input.analog_dpad_mode[i])
         continue;

      input_push_analog_dpad(settings->input.binds[i],
            settings->input.analog_dpad_mode[i]);
      input_push_analog_dpad(settings->input.autoconf_binds[i],
            settings->input.analog_dpad_mode[i]);
   }

   if ((settings->video.frame_delay > 0) && 
         !input_driver_is_nonblock_state())
      retro_sleep(settings->video.frame_delay);

   core_run();

#ifdef HAVE_CHEEVOS
   cheevos_test();
#endif

   for (i = 0; i < settings->input.max_users; i++)
   {
      if (!settings->input.analog_dpad_mode[i])
         continue;

      input_pop_analog_dpad(settings->input.binds[i]);
      input_pop_analog_dpad(settings->input.autoconf_binds[i]);
   }

   if (bsv_movie_ctl(BSV_MOVIE_CTL_IS_INITED, NULL))
      bsv_movie_ctl(BSV_MOVIE_CTL_SET_FRAME_END, NULL);

#ifdef HAVE_NETPLAY
   netplay_driver_ctl(RARCH_NETPLAY_CTL_POST_FRAME, NULL);
#endif

#if defined(HAVE_THREADS)
   autosave_unlock();
#endif

   if (!settings->fastforward_ratio)
      return 0;
#ifdef HAVE_MENU
end:
#endif

   current                        = cpu_features_get_time_usec();
   target                         = frame_limit_last_time + 
      frame_limit_minimum_time;
   to_sleep_ms                    = (target - current) / 1000;

   if (to_sleep_ms > 0)
   {
      *sleep_ms = (unsigned)to_sleep_ms;
      /* Combat jitter a bit. */
      frame_limit_last_time += frame_limit_minimum_time;
      return 1;
   }

   frame_limit_last_time  = cpu_features_get_time_usec();

   return 0;
}
Beispiel #18
0
/**
 * menu_iterate:
 * @input                    : input sample for this frame
 * @old_input                : input sample of the previous frame
 * @trigger_input            : difference' input sample - difference
 *                             between 'input' and 'old_input'
 *
 * Runs RetroArch menu for one frame.
 *
 * Returns: 0 on success, -1 if we need to quit out of the loop.
 **/
int generic_menu_iterate(void *data, void *userdata, enum menu_action action)
{
   menu_entry_t entry;
   enum action_iterate_type iterate_type;
   size_t selection               = 0;
   unsigned file_type             = 0;
   int ret                        = 0;
   uint32_t hash                  = 0;
   enum msg_hash_enums enum_idx   = MSG_UNKNOWN;
   const char *label              = NULL;
   menu_handle_t *menu            = (menu_handle_t*)data;

   menu_entries_get_last_stack(NULL, &label, &file_type, &enum_idx, NULL);

   if (!menu)
      return 0;
   if (!menu_navigation_ctl(MENU_NAVIGATION_CTL_GET_SELECTION, &selection))
      return 0;

   menu->menu_state.msg[0]   = '\0';
   hash                      = msg_hash_calculate(label);
   iterate_type              = action_iterate_type(hash);

   menu_driver_set_binding_state(iterate_type == ITERATE_TYPE_BIND);

   if (     action != MENU_ACTION_NOOP
         || menu_entries_ctl(MENU_ENTRIES_CTL_NEEDS_REFRESH, NULL)
         || menu_display_get_update_pending())
   {
      BIT64_SET(menu->state, MENU_STATE_RENDER_FRAMEBUFFER);
   }

   switch (iterate_type)
   {
      case ITERATE_TYPE_HELP:
         ret = menu_dialog_iterate(
               menu->menu_state.msg, sizeof(menu->menu_state.msg), label);
         BIT64_SET(menu->state, MENU_STATE_RENDER_MESSAGEBOX);
         BIT64_SET(menu->state, MENU_STATE_POST_ITERATE);
         if (ret == 1 || action == MENU_ACTION_OK)
         {
            BIT64_SET(menu->state, MENU_STATE_POP_STACK);
            menu_dialog_set_active(false);
         }

         if (action == MENU_ACTION_CANCEL)
         {
            BIT64_SET(menu->state, MENU_STATE_POP_STACK);
            menu_dialog_set_active(false);
         }
         break;
      case ITERATE_TYPE_BIND:
         {
            menu_input_ctx_bind_t bind;

            bind.s   = menu->menu_state.msg;
            bind.len = sizeof(menu->menu_state.msg);

            if (menu_input_key_bind_iterate(&bind))
            {
               menu_entries_pop_stack(&selection, 0, 0);
               menu_navigation_ctl(
                     MENU_NAVIGATION_CTL_SET_SELECTION, &selection);
            }
            else
               BIT64_SET(menu->state, MENU_STATE_RENDER_MESSAGEBOX);
         }
         break;
      case ITERATE_TYPE_INFO:
         {
            file_list_t *selection_buf = menu_entries_get_selection_buf_ptr(0);
            menu_file_list_cbs_t *cbs  =
               menu_entries_get_actiondata_at_offset(selection_buf, selection);

            if (cbs->enum_idx != MSG_UNKNOWN)
            {
               ret = menu_hash_get_help_enum(cbs->enum_idx,
                     menu->menu_state.msg, sizeof(menu->menu_state.msg));
            }
            else
            {
               unsigned type = 0;
               enum msg_hash_enums enum_idx = MSG_UNKNOWN;
               menu_entries_get_at_offset(selection_buf, selection,
                     NULL, NULL, &type, NULL, NULL);

               switch (type)
               {
                  case FILE_TYPE_FONT:
                     enum_idx = MENU_ENUM_LABEL_FILE_BROWSER_FONT;
                     break;
                  case FILE_TYPE_RDB:
                     enum_idx = MENU_ENUM_LABEL_FILE_BROWSER_RDB;
                     break;
                  case FILE_TYPE_OVERLAY:
                     enum_idx = MENU_ENUM_LABEL_FILE_BROWSER_OVERLAY;
                     break;
                  case FILE_TYPE_CHEAT:
                     enum_idx = MENU_ENUM_LABEL_FILE_BROWSER_CHEAT;
                     break;
                  case FILE_TYPE_SHADER_PRESET:
                     enum_idx = MENU_ENUM_LABEL_FILE_BROWSER_SHADER_PRESET;
                     break;
                  case FILE_TYPE_SHADER:
                     enum_idx = MENU_ENUM_LABEL_FILE_BROWSER_SHADER;
                     break;
                  case FILE_TYPE_REMAP:
                     enum_idx = MENU_ENUM_LABEL_FILE_BROWSER_REMAP;
                     break;
                  case FILE_TYPE_RECORD_CONFIG:
                     enum_idx = MENU_ENUM_LABEL_FILE_BROWSER_RECORD_CONFIG;
                     break;
                  case FILE_TYPE_CURSOR:
                     enum_idx = MENU_ENUM_LABEL_FILE_BROWSER_CURSOR;
                     break;
                  case FILE_TYPE_CONFIG:
                     enum_idx = MENU_ENUM_LABEL_FILE_BROWSER_CONFIG;
                     break;
                  case FILE_TYPE_CARCHIVE:
                     enum_idx = MENU_ENUM_LABEL_FILE_BROWSER_COMPRESSED_ARCHIVE;
                     break;
                  case FILE_TYPE_DIRECTORY:
                     enum_idx = MENU_ENUM_LABEL_FILE_BROWSER_DIRECTORY;
                     break;
                  case FILE_TYPE_VIDEOFILTER:            /* TODO/FIXME */
                  case FILE_TYPE_AUDIOFILTER:            /* TODO/FIXME */
                  case FILE_TYPE_SHADER_SLANG:           /* TODO/FIXME */
                  case FILE_TYPE_SHADER_GLSL:            /* TODO/FIXME */
                  case FILE_TYPE_SHADER_HLSL:            /* TODO/FIXME */
                  case FILE_TYPE_SHADER_CG:              /* TODO/FIXME */
                  case FILE_TYPE_SHADER_PRESET_GLSLP:    /* TODO/FIXME */
                  case FILE_TYPE_SHADER_PRESET_HLSLP:    /* TODO/FIXME */
                  case FILE_TYPE_SHADER_PRESET_CGP:      /* TODO/FIXME */
                  case FILE_TYPE_SHADER_PRESET_SLANGP:   /* TODO/FIXME */
                  case FILE_TYPE_PLAIN:
                     enum_idx = MENU_ENUM_LABEL_FILE_BROWSER_PLAIN_FILE;
                     break;
                  default:
                     break;
               }

               if (enum_idx != MSG_UNKNOWN)
                  ret = menu_hash_get_help_enum(enum_idx,
                        menu->menu_state.msg, sizeof(menu->menu_state.msg));

            }
         }
         BIT64_SET(menu->state, MENU_STATE_RENDER_MESSAGEBOX);
         BIT64_SET(menu->state, MENU_STATE_POST_ITERATE);
         if (action == MENU_ACTION_OK || action == MENU_ACTION_CANCEL)
         {
            BIT64_SET(menu->state, MENU_STATE_POP_STACK);
         }
         menu_dialog_set_active(false);
         break;
      case ITERATE_TYPE_DEFAULT:
         /* FIXME: Crappy hack, needed for mouse controls
          * to not be completely broken in case we press back.
          *
          * We need to fix this entire mess, mouse controls
          * should not rely on a hack like this in order to work. */
         selection = MAX(MIN(selection, (menu_entries_get_size() - 1)), 0);

         menu_entry_get(&entry, 0, selection, NULL, false);
         ret = menu_entry_action(&entry, selection, (enum menu_action)action);

         if (ret)
            goto end;

         BIT64_SET(menu->state, MENU_STATE_POST_ITERATE);

         /* Have to defer it so we let settings refresh. */
         menu_dialog_push();
         break;
   }

   BIT64_SET(menu->state, MENU_STATE_BLIT);

   if (BIT64_GET(menu->state, MENU_STATE_POP_STACK))
   {
      size_t new_selection_ptr = selection;
      menu_entries_pop_stack(&new_selection_ptr, 0, 0);
      menu_navigation_ctl(MENU_NAVIGATION_CTL_SET_SELECTION, &selection);
   }

   if (BIT64_GET(menu->state, MENU_STATE_POST_ITERATE))
      menu_input_post_iterate(&ret, action);

end:
   if (ret)
      return -1;
   return 0;
}
Beispiel #19
0
static void iohidmanager_hid_device_input_callback(void *data, IOReturn result,
      void* sender, IOHIDValueRef value)
{
   iohidmanager_hid_t *hid = (iohidmanager_hid_t*)hid_driver_get_data();
   struct iohidmanager_hid_adapter *adapter = (struct iohidmanager_hid_adapter*)data;
   IOHIDElementRef element           = IOHIDValueGetElement(value);
   uint32_t type                     = IOHIDElementGetType(element);
   uint32_t page                     = IOHIDElementGetUsagePage(element);
   uint32_t use                      = IOHIDElementGetUsage(element);

   if (type != kIOHIDElementTypeInput_Misc)
      if (type != kIOHIDElementTypeInput_Button)
         if (type != kIOHIDElementTypeInput_Axis)
            return;

   /* Joystick handler.
    * TODO: Can GamePad work the same? */

   switch (page)
   {
      case kHIDPage_GenericDesktop:
         switch (type)
         {
            case kIOHIDElementTypeInput_Misc:
               switch (use)
               {
                  case kHIDUsage_GD_Hatswitch:
                     break;
                  default:
                     {
                        int i;
                        // +0/-0   =>   Left Stick Horizontal       => 48
                        // +1/-1   =>   Left Stick Vertical         => 49
                        // +2/-2   =>   Right Stick Horizontal      => 51
                        // +3/-3   =>   Right Stick Vertical        => 52
                        // +4/-4   =>   Left Trigger (if exists)    => 50
                        // +5/-5   =>   Right Trigger (if exists)   => 53
                        static const uint32_t axis_use_ids[6] = { 48, 49, 51, 52, 50, 53 };

                        for (i = 0; i < 6; i ++)
                        {
                           CFIndex min   = IOHIDElementGetPhysicalMin(element);
                           CFIndex state = IOHIDValueGetIntegerValue(value) - min;
                           CFIndex max   = IOHIDElementGetPhysicalMax(element) - min;
                           float val     = (float)state / (float)max;

                           if (use != axis_use_ids[i])
                              continue;

                           hid->axes[adapter->slot][i] =
                              ((val * 2.0f) - 1.0f) * 32767.0f;
                        }
                     }
                     break;
               }
               break;
         }
         break;
      case kHIDPage_Button:
         switch (type)
         {
            case kIOHIDElementTypeInput_Button:
               {
                  CFIndex state = IOHIDValueGetIntegerValue(value);
                  unsigned   id = use - 1;

                  if (state)
                     BIT64_SET(hid->buttons[adapter->slot], id);
                  else
                     BIT64_CLEAR(hid->buttons[adapter->slot], id);
               }
               break;
         }
         break;
   }
}
Beispiel #20
0
static int menu_input_mouse_post_iterate(uint64_t *input_mouse,
      menu_file_list_cbs_t *cbs, unsigned action)
{
   settings_t *settings       = config_get_ptr();
   static bool mouse_oldleft  = false;
   static bool mouse_oldright = false;

   if (
         !settings->menu.mouse.enable
#ifdef HAVE_OVERLAY
         || (settings->input.overlay_enable && input_overlay_is_alive(NULL))
#endif
         )
   {
      /* HACK: Need to lie to avoid false hits if mouse is held 
       * when entering the RetroArch window. */

      /* This happens if, for example, someone double clicks the 
       * window border to maximize it.
       *
       * The proper fix is, of course, triggering on WM_LBUTTONDOWN 
       * rather than this state change. */
      mouse_oldleft   = true;
      mouse_oldright  = true;
      return 0;
   }

   if (menu_input_mouse_state(MENU_MOUSE_LEFT_BUTTON))
   {
      if (!mouse_oldleft)
      {
         size_t selection;
         menu_input_t *menu_input = menu_input_get_ptr();

         menu_navigation_ctl(MENU_NAVIGATION_CTL_GET_SELECTION, &selection);

         BIT64_SET(*input_mouse, MENU_MOUSE_ACTION_BUTTON_L);

         mouse_oldleft = true;

         if ((menu_input->mouse.ptr == selection) && cbs && cbs->action_select)
         {
            BIT64_SET(*input_mouse, MENU_MOUSE_ACTION_BUTTON_L_TOGGLE);
         }
         else if (menu_input->mouse.ptr <= (menu_entries_get_size() - 1))
         {
            BIT64_SET(*input_mouse, MENU_MOUSE_ACTION_BUTTON_L_SET_NAVIGATION);
         }
      }
   }
   else
      mouse_oldleft = false;

   if (menu_input_mouse_state(MENU_MOUSE_RIGHT_BUTTON))
   {
      if (!mouse_oldright)
      {
         mouse_oldright = true;
         BIT64_SET(*input_mouse, MENU_MOUSE_ACTION_BUTTON_R);
      }
   }
   else
      mouse_oldright = false;

   if (menu_input_mouse_state(MENU_MOUSE_WHEEL_DOWN))
   {
      BIT64_SET(*input_mouse, MENU_MOUSE_ACTION_WHEEL_DOWN);
   }

   if (menu_input_mouse_state(MENU_MOUSE_WHEEL_UP))
   {
      BIT64_SET(*input_mouse, MENU_MOUSE_ACTION_WHEEL_UP);
   }

   if (menu_input_mouse_state(MENU_MOUSE_HORIZ_WHEEL_DOWN))
   {
      BIT64_SET(*input_mouse, MENU_MOUSE_ACTION_HORIZ_WHEEL_DOWN);
   }

   if (menu_input_mouse_state(MENU_MOUSE_HORIZ_WHEEL_UP))
   {
      BIT64_SET(*input_mouse, MENU_MOUSE_ACTION_HORIZ_WHEEL_UP);
   }

   return 0;
}
Beispiel #21
0
static int menu_input_mouse_post_iterate(uint64_t *input_mouse,
      menu_file_list_cbs_t *cbs,
      menu_entry_t *entry, unsigned action)
{
   driver_t      *driver  = driver_get_ptr();
   settings_t *settings   = config_get_ptr();
   menu_handle_t *menu    = menu_driver_get_ptr();
   menu_list_t *menu_list = menu_list_get_ptr();
   menu_navigation_t *nav = menu_navigation_get_ptr();

   *input_mouse = MOUSE_ACTION_NONE;

   if (!menu)
      return -1;

   if (!settings->menu.mouse.enable
#ifdef HAVE_OVERLAY
       || (settings->input.overlay_enable && driver && driver->overlay)
#endif
       )
   {
      menu->mouse.wheeldown = false;
      menu->mouse.wheelup   = false;
      menu->mouse.oldleft   = false;
      menu->mouse.oldright  = false;
      return 0;
   }

   if (menu->mouse.left)
   {
      if (!menu->mouse.oldleft)
      {
         BIT64_SET(*input_mouse, MOUSE_ACTION_BUTTON_L);

         rarch_setting_t *setting = menu_setting_find(
               menu_list->selection_buf->list[nav->selection_ptr].label);
         menu->mouse.oldleft = true;

         if (menu->mouse.y < menu->header_height)
         {
            menu_list_pop_stack(menu_list);
            return 0;
         }
         if (menu->mouse.ptr == nav->selection_ptr
            && cbs && cbs->action_right && setting &&
            (setting->type == ST_BOOL || setting->type == ST_UINT || setting->type == ST_FLOAT
             || setting->type == ST_STRING))
         {
            BIT64_SET(*input_mouse, MOUSE_ACTION_BUTTON_L_TOGGLE);
         }
         else if (menu->mouse.ptr == nav->selection_ptr
            && cbs && cbs->action_ok)
         {
            BIT64_SET(*input_mouse, MOUSE_ACTION_BUTTON_L_OK);
         }
         else if (menu->mouse.ptr <= menu_list_get_size(menu_list)-1)
         {
            BIT64_SET(*input_mouse, MOUSE_ACTION_BUTTON_L_SET_NAVIGATION);
         }
      }
   }
   else
      menu->mouse.oldleft = false;

   if (menu->mouse.right)
   {
      if (!menu->mouse.oldright)
      {
         menu->mouse.oldright = true;
         BIT64_SET(*input_mouse, MOUSE_ACTION_BUTTON_R);
      }
   }
   else
      menu->mouse.oldright = false;

   if (menu->mouse.wheeldown)
   {
      BIT64_SET(*input_mouse, MOUSE_ACTION_WHEEL_DOWN);
   }

   if (menu->mouse.wheelup)
   {
      BIT64_SET(*input_mouse, MOUSE_ACTION_WHEEL_UP);
   }

   return 0;
}
Beispiel #22
0
/**
 * menu_iterate:
 * @input                    : input sample for this frame
 * @old_input                : input sample of the previous frame
 * @trigger_input            : difference' input sample - difference
 *                             between 'input' and 'old_input'
 *
 * Runs RetroArch menu for one frame.
 *
 * Returns: 0 on success, -1 if we need to quit out of the loop. 
 **/
int generic_menu_iterate(enum menu_action action)
{
   size_t selection;
   menu_entry_t entry;
   enum action_iterate_type iterate_type;
   const char *label          = NULL;
   int ret                    = 0;
   uint32_t label_hash        = 0;
   uint32_t hash              = 0;
   menu_handle_t *menu        = menu_driver_get_ptr();
   file_list_t *menu_stack    = menu_entries_get_menu_stack_ptr();
   file_list_t *selection_buf = menu_entries_get_selection_buf_ptr();

   menu_entries_get_last_stack(NULL, &label, NULL, NULL);

   if (!menu)
      return 0;
   if (!menu_navigation_ctl(MENU_NAVIGATION_CTL_GET_SELECTION, &selection))
      return 0;

   menu->menu_state.msg[0]   = '\0';
   hash                      = menu_hash_calculate(label);
   iterate_type              = action_iterate_type(hash);

   if (action != MENU_ACTION_NOOP || menu_entries_needs_refresh() || menu_display_ctl(MENU_DISPLAY_CTL_UPDATE_PENDING, NULL))
   {
      BIT64_SET(menu->state, MENU_STATE_RENDER_FRAMEBUFFER);
   }

   switch (iterate_type)
   {
      case ITERATE_TYPE_HELP:
         ret = action_iterate_help(menu->menu_state.msg, sizeof(menu->menu_state.msg), label);
         BIT64_SET(menu->state, MENU_STATE_RENDER_MESSAGEBOX);
         BIT64_SET(menu->state, MENU_STATE_POST_ITERATE);
         if (ret == 1 || action == MENU_ACTION_OK)
            BIT64_SET(menu->state, MENU_STATE_POP_STACK);
         break;
      case ITERATE_TYPE_BIND:
         if (menu_input_key_bind_iterate(menu->menu_state.msg, sizeof(menu->menu_state.msg)))
         {
            menu_entries_pop_stack(&selection);
            menu_navigation_ctl(MENU_NAVIGATION_CTL_SET_SELECTION, &selection);
         }
         else
            BIT64_SET(menu->state, MENU_STATE_RENDER_MESSAGEBOX);
         break;
      case ITERATE_TYPE_INFO:
         {
            menu_file_list_cbs_t *cbs = menu_entries_get_actiondata_at_offset(selection_buf, selection);
            rarch_setting_t *setting  = cbs->setting;

            if (setting)
            {
               char needle[PATH_MAX_LENGTH];
               strlcpy(needle, menu_setting_get_name(setting), sizeof(needle));
               label_hash       = menu_hash_calculate(needle);
            }

            ret = menu_hash_get_help(label_hash, menu->menu_state.msg, sizeof(menu->menu_state.msg));
         }
         BIT64_SET(menu->state, MENU_STATE_RENDER_MESSAGEBOX);
         BIT64_SET(menu->state, MENU_STATE_POST_ITERATE);
         if (action == MENU_ACTION_OK)
            BIT64_SET(menu->state, MENU_STATE_POP_STACK);
         break;
      case ITERATE_TYPE_DEFAULT:
         /* FIXME: Crappy hack, needed for mouse controls to not be completely broken
          * in case we press back.
          *
          * We need to fix this entire mess, mouse controls should not rely on a 
          * hack like this in order to work. */
         selection = max(min(selection, (menu_entries_get_size() - 1)), 0);

         menu_entry_get(&entry,    selection, NULL, false);
         ret = menu_entry_action(&entry, selection, (enum menu_action)action);

         if (ret)
            goto end;

         BIT64_SET(menu->state, MENU_STATE_POST_ITERATE);

         /* Have to defer it so we let settings refresh. */
         if (menu->push_help_screen)
         {
            menu_displaylist_info_t info = {0};

            info.list = menu_stack;
            strlcpy(info.label,
                  menu_hash_to_str(MENU_LABEL_HELP),
                  sizeof(info.label));

            menu_displaylist_push_list(&info, DISPLAYLIST_HELP);
         }
         break;
   }

   BIT64_SET(menu->state, MENU_STATE_BLIT);

   if (BIT64_GET(menu->state, MENU_STATE_POP_STACK))
   {
      size_t new_selection_ptr = selection;
      menu_entries_pop_stack(&new_selection_ptr);
      menu_navigation_ctl(MENU_NAVIGATION_CTL_SET_SELECTION, &selection);
   }
   
   if (BIT64_GET(menu->state, MENU_STATE_POST_ITERATE))
      menu_input_post_iterate(&ret, action);

end:
   if (ret)
      return -1;
   return 0;
}
Beispiel #23
0
static int menu_input_mouse_post_iterate(uint64_t *input_mouse,
      menu_file_list_cbs_t *cbs, unsigned action)
{
   settings_t *settings     = config_get_ptr();
   menu_display_t *disp     = menu_display_get_ptr();
   menu_input_t *menu_input = menu_input_get_ptr();
   menu_list_t *menu_list   = menu_list_get_ptr();
   menu_navigation_t *nav   = menu_navigation_get_ptr();

   *input_mouse = MOUSE_ACTION_NONE;

   if (!settings->menu.mouse.enable
#ifdef HAVE_OVERLAY
       || (settings->input.overlay_enable && input_overlay_is_alive())
#endif
       )
   {
      menu_input->mouse.wheeldown = false;
      menu_input->mouse.wheelup   = false;
      menu_input->mouse.oldleft   = false;
      menu_input->mouse.oldright  = false;
      return 0;
   }

   if (menu_input->mouse.left)
   {
      if (!menu_input->mouse.oldleft)
      {
         BIT64_SET(*input_mouse, MOUSE_ACTION_BUTTON_L);

         menu_input->mouse.oldleft = true;

         if ((unsigned)menu_input->mouse.y < disp->header_height)
         {
            menu_list_pop_stack(menu_list, &nav->selection_ptr);
            return 0;
         }
         if (
               (menu_input->mouse.ptr == nav->selection_ptr) &&
               cbs &&
               cbs->action_select            )
         {
            BIT64_SET(*input_mouse, MOUSE_ACTION_BUTTON_L_TOGGLE);
         }
         else if (menu_input->mouse.ptr <= menu_list_get_size(menu_list)-1)
         {
            BIT64_SET(*input_mouse, MOUSE_ACTION_BUTTON_L_SET_NAVIGATION);
         }
      }
   }
   else
      menu_input->mouse.oldleft = false;

   if (menu_input->mouse.right)
   {
      if (!menu_input->mouse.oldright)
      {
         menu_input->mouse.oldright = true;
         BIT64_SET(*input_mouse, MOUSE_ACTION_BUTTON_R);
      }
   }
   else
      menu_input->mouse.oldright = false;

   if (menu_input->mouse.wheeldown)
   {
      BIT64_SET(*input_mouse, MOUSE_ACTION_WHEEL_DOWN);
   }

   if (menu_input->mouse.wheelup)
   {
      BIT64_SET(*input_mouse, MOUSE_ACTION_WHEEL_UP);
   }

   return 0;
}
Beispiel #24
0
static void gx_joypad_poll(void)
{
   unsigned i, j, port;
   uint8_t gcpad = 0;
   uint64_t state_p1;
   uint64_t check_menu_toggle;

   pad_state[0] = 0;
   pad_state[1] = 0;
   pad_state[2] = 0;
   pad_state[3] = 0;

   gcpad = PAD_ScanPads();

#ifdef HW_RVL
   if (g_quit)
   {
      runloop_ctl(RUNLOOP_CTL_SET_SHUTDOWN, NULL);
      return;
   }

   WPAD_ReadPending(WPAD_CHAN_ALL, NULL);
#endif

   for (port = 0; port < MAX_PADS; port++)
   {
      uint32_t down = 0, ptype = WPAD_EXP_NOCONTROLLER;
      uint64_t *state_cur = &pad_state[port];

      if (gcpad & (1 << port))
      {
         int16_t ls_x, ls_y, rs_x, rs_y;
         uint64_t menu_combo = 0;

         down = PAD_ButtonsHeld(port);

         *state_cur |= (down & PAD_BUTTON_A) ? (UINT64_C(1) << GX_GC_A) : 0;
         *state_cur |= (down & PAD_BUTTON_B) ? (UINT64_C(1) << GX_GC_B) : 0;
         *state_cur |= (down & PAD_BUTTON_X) ? (UINT64_C(1) << GX_GC_X) : 0;
         *state_cur |= (down & PAD_BUTTON_Y) ? (UINT64_C(1) << GX_GC_Y) : 0;
         *state_cur |= (down & PAD_BUTTON_UP) ? (UINT64_C(1) << GX_GC_UP) : 0;
         *state_cur |= (down & PAD_BUTTON_DOWN) ? (UINT64_C(1) << GX_GC_DOWN) : 0;
         *state_cur |= (down & PAD_BUTTON_LEFT) ? (UINT64_C(1) << GX_GC_LEFT) : 0;
         *state_cur |= (down & PAD_BUTTON_RIGHT) ? (UINT64_C(1) << GX_GC_RIGHT) : 0;
         *state_cur |= (down & PAD_BUTTON_START) ? (UINT64_C(1) << GX_GC_START) : 0;
         *state_cur |= (down & PAD_TRIGGER_Z) ? (UINT64_C(1) << GX_GC_Z_TRIGGER) : 0;
         *state_cur |= ((down & PAD_TRIGGER_L) || PAD_TriggerL(port) > 127) ? (UINT64_C(1) << GX_GC_L_TRIGGER) : 0;
         *state_cur |= ((down & PAD_TRIGGER_R) || PAD_TriggerR(port) > 127) ? (UINT64_C(1) << GX_GC_R_TRIGGER) : 0;

         ls_x = (int16_t)PAD_StickX(port) * 256;
         ls_y = (int16_t)PAD_StickY(port) * -256;
         rs_x = (int16_t)PAD_SubStickX(port) * 256;
         rs_y = (int16_t)PAD_SubStickY(port) * -256;

         analog_state[port][RETRO_DEVICE_INDEX_ANALOG_LEFT][RETRO_DEVICE_ID_ANALOG_X] = ls_x;
         analog_state[port][RETRO_DEVICE_INDEX_ANALOG_LEFT][RETRO_DEVICE_ID_ANALOG_Y] = ls_y;
         analog_state[port][RETRO_DEVICE_INDEX_ANALOG_RIGHT][RETRO_DEVICE_ID_ANALOG_X] = rs_x;
         analog_state[port][RETRO_DEVICE_INDEX_ANALOG_RIGHT][RETRO_DEVICE_ID_ANALOG_Y] = rs_y;

         menu_combo = (UINT64_C(1) << GX_GC_START) | (UINT64_C(1) << GX_GC_Z_TRIGGER) |
                      (UINT64_C(1) << GX_GC_L_TRIGGER) | (UINT64_C(1) << GX_GC_R_TRIGGER);

         if ((*state_cur & menu_combo) == menu_combo)
            *state_cur |= (UINT64_C(1) << GX_GC_HOME);

         ptype = WPAD_EXP_GAMECUBE;
      }
#ifdef HW_RVL
      else if (WPADProbe(port, &ptype) == WPAD_ERR_NONE)
      {
         WPADData *wpaddata = (WPADData*)WPAD_Data(port);

         down = wpaddata->btns_h;

         *state_cur |= (down & WPAD_BUTTON_A) ? (UINT64_C(1) << GX_WIIMOTE_A) : 0;
         *state_cur |= (down & WPAD_BUTTON_B) ? (UINT64_C(1) << GX_WIIMOTE_B) : 0;
         *state_cur |= (down & WPAD_BUTTON_1) ? (UINT64_C(1) << GX_WIIMOTE_1) : 0;
         *state_cur |= (down & WPAD_BUTTON_2) ? (UINT64_C(1) << GX_WIIMOTE_2) : 0;
         *state_cur |= (down & WPAD_BUTTON_PLUS) ? (UINT64_C(1) << GX_WIIMOTE_PLUS) : 0;
         *state_cur |= (down & WPAD_BUTTON_MINUS) ? (UINT64_C(1) << GX_WIIMOTE_MINUS) : 0;
         *state_cur |= (down & WPAD_BUTTON_HOME) ? (UINT64_C(1) << GX_WIIMOTE_HOME) : 0;

         if (ptype != WPAD_EXP_NUNCHUK)
         {
            /* Rotated d-pad on Wiimote. */
            *state_cur |= (down & WPAD_BUTTON_UP) ? (UINT64_C(1) << GX_WIIMOTE_LEFT) : 0;
            *state_cur |= (down & WPAD_BUTTON_DOWN) ? (UINT64_C(1) << GX_WIIMOTE_RIGHT) : 0;
            *state_cur |= (down & WPAD_BUTTON_LEFT) ? (UINT64_C(1) << GX_WIIMOTE_DOWN) : 0;
            *state_cur |= (down & WPAD_BUTTON_RIGHT) ? (UINT64_C(1) << GX_WIIMOTE_UP) : 0;
         }

         if (ptype == WPAD_EXP_CLASSIC)
         {
            *state_cur |= (down & WPAD_CLASSIC_BUTTON_A) ? (UINT64_C(1) << GX_CLASSIC_A) : 0;
            *state_cur |= (down & WPAD_CLASSIC_BUTTON_B) ? (UINT64_C(1) << GX_CLASSIC_B) : 0;
            *state_cur |= (down & WPAD_CLASSIC_BUTTON_X) ? (UINT64_C(1) << GX_CLASSIC_X) : 0;
            *state_cur |= (down & WPAD_CLASSIC_BUTTON_Y) ? (UINT64_C(1) << GX_CLASSIC_Y) : 0;
            *state_cur |= (down & WPAD_CLASSIC_BUTTON_UP) ? (UINT64_C(1) << GX_CLASSIC_UP) : 0;
            *state_cur |= (down & WPAD_CLASSIC_BUTTON_DOWN) ? (UINT64_C(1) << GX_CLASSIC_DOWN) : 0;
            *state_cur |= (down & WPAD_CLASSIC_BUTTON_LEFT) ? (UINT64_C(1) << GX_CLASSIC_LEFT) : 0;
            *state_cur |= (down & WPAD_CLASSIC_BUTTON_RIGHT) ? (UINT64_C(1) << GX_CLASSIC_RIGHT) : 0;
            *state_cur |= (down & WPAD_CLASSIC_BUTTON_PLUS) ? (UINT64_C(1) << GX_CLASSIC_PLUS) : 0;
            *state_cur |= (down & WPAD_CLASSIC_BUTTON_MINUS) ? (UINT64_C(1) << GX_CLASSIC_MINUS) : 0;
            *state_cur |= (down & WPAD_CLASSIC_BUTTON_HOME) ? (UINT64_C(1) << GX_CLASSIC_HOME) : 0;
            *state_cur |= (down & WPAD_CLASSIC_BUTTON_FULL_L) ? (UINT64_C(1) << GX_CLASSIC_L_TRIGGER) : 0;
            *state_cur |= (down & WPAD_CLASSIC_BUTTON_FULL_R) ? (UINT64_C(1) << GX_CLASSIC_R_TRIGGER) : 0;
            *state_cur |= (down & WPAD_CLASSIC_BUTTON_ZL) ? (UINT64_C(1) << GX_CLASSIC_ZL_TRIGGER) : 0;
            *state_cur |= (down & WPAD_CLASSIC_BUTTON_ZR) ? (UINT64_C(1) << GX_CLASSIC_ZR_TRIGGER) : 0;

            analog_state[port][RETRO_DEVICE_INDEX_ANALOG_LEFT][RETRO_DEVICE_ID_ANALOG_X]  = WPAD_StickX(wpaddata, 0);
            analog_state[port][RETRO_DEVICE_INDEX_ANALOG_LEFT][RETRO_DEVICE_ID_ANALOG_Y]  = WPAD_StickY(wpaddata, 0);
            analog_state[port][RETRO_DEVICE_INDEX_ANALOG_RIGHT][RETRO_DEVICE_ID_ANALOG_X] = WPAD_StickX(wpaddata, 1);
            analog_state[port][RETRO_DEVICE_INDEX_ANALOG_RIGHT][RETRO_DEVICE_ID_ANALOG_Y] = WPAD_StickY(wpaddata, 1);
         }
         else if (ptype == WPAD_EXP_NUNCHUK)
         {
            /* Wiimote is held upright with nunchuk,
             * do not change d-pad orientation. */
            *state_cur |= (down & WPAD_BUTTON_UP) ? (UINT64_C(1) << GX_WIIMOTE_UP) : 0;
            *state_cur |= (down & WPAD_BUTTON_DOWN) ? (UINT64_C(1) << GX_WIIMOTE_DOWN) : 0;
            *state_cur |= (down & WPAD_BUTTON_LEFT) ? (UINT64_C(1) << GX_WIIMOTE_LEFT) : 0;
            *state_cur |= (down & WPAD_BUTTON_RIGHT) ? (UINT64_C(1) << GX_WIIMOTE_RIGHT) : 0;

            *state_cur |= (down & WPAD_NUNCHUK_BUTTON_Z) ? (UINT64_C(1) << GX_NUNCHUK_Z) : 0;
            *state_cur |= (down & WPAD_NUNCHUK_BUTTON_C) ? (UINT64_C(1) << GX_NUNCHUK_C) : 0;

            analog_state[port][RETRO_DEVICE_INDEX_ANALOG_LEFT][RETRO_DEVICE_ID_ANALOG_X] = WPAD_StickX(wpaddata, 0);
            analog_state[port][RETRO_DEVICE_INDEX_ANALOG_LEFT][RETRO_DEVICE_ID_ANALOG_Y] = WPAD_StickY(wpaddata, 0);
         }
      }
#endif

      if (ptype != pad_type[port])
         handle_hotplug(port, ptype);

      for (i = 0; i < 2; i++)
         for (j = 0; j < 2; j++)
            if (analog_state[port][i][j] == -0x8000)
               analog_state[port][i][j] = -0x7fff;
   }

   state_p1 = pad_state[0];

   BIT64_CLEAR(lifecycle_state, RARCH_MENU_TOGGLE);
   if (g_menu)
   {
      state_p1 |= (UINT64_C(1) << GX_GC_HOME);
      g_menu = false;
   }

   check_menu_toggle = UINT64_C(1) << GX_GC_HOME;
#ifdef HW_RVL
   check_menu_toggle |= (UINT64_C(1) << GX_WIIMOTE_HOME) | (UINT64_C(1) << GX_CLASSIC_HOME);
#endif

   if (check_menu_toggle & state_p1)
      BIT64_SET(lifecycle_state, RARCH_MENU_TOGGLE);
}
Beispiel #25
0
static int menu_input_mouse_post_iterate(uint64_t *input_mouse,
      menu_file_list_cbs_t *cbs, unsigned action)
{
   settings_t *settings       = config_get_ptr();
   static bool mouse_oldleft  = false;
   static bool mouse_oldright = false;

   *input_mouse = MENU_MOUSE_ACTION_NONE;


   if (
         !settings->menu.mouse.enable 
#ifdef HAVE_OVERLAY
         || (settings->input.overlay_enable && input_overlay_is_alive(NULL))
#endif
         )
   {
      mouse_oldleft   = false;
      mouse_oldright  = false;
      return 0;
   }

   if (menu_input_mouse_state(MENU_MOUSE_LEFT_BUTTON))
   {
      if (!mouse_oldleft)
      {
         size_t selection;
         unsigned header_height;
         menu_input_t *menu_input = menu_input_get_ptr();

         menu_navigation_ctl(MENU_NAVIGATION_CTL_GET_SELECTION, &selection);
         header_height = menu_display_get_header_height();

         BIT64_SET(*input_mouse, MENU_MOUSE_ACTION_BUTTON_L);

         mouse_oldleft = true;

         /* Back button */
         if ((unsigned)menu_input_mouse_state(MENU_MOUSE_X_AXIS) < header_height)
         {
            menu_entries_pop_stack(&selection, 0, 1);
            menu_navigation_ctl(MENU_NAVIGATION_CTL_SET_SELECTION, &selection);
            return 0;
         }
         if ((menu_input->mouse.ptr == selection) && cbs && cbs->action_select)
         {
            BIT64_SET(*input_mouse, MENU_MOUSE_ACTION_BUTTON_L_TOGGLE);
         }
         else if (menu_input->mouse.ptr <= (menu_entries_get_size() - 1))
         {
            BIT64_SET(*input_mouse, MENU_MOUSE_ACTION_BUTTON_L_SET_NAVIGATION);
         }
      }
   }
   else
      mouse_oldleft = false;

   if (menu_input_mouse_state(MENU_MOUSE_RIGHT_BUTTON))
   {
      if (!mouse_oldright)
      {
         mouse_oldright = true;
         BIT64_SET(*input_mouse, MENU_MOUSE_ACTION_BUTTON_R);
      }
   }
   else
      mouse_oldright = false;

   if (menu_input_mouse_state(MENU_MOUSE_WHEEL_DOWN))
   {
      BIT64_SET(*input_mouse, MENU_MOUSE_ACTION_WHEEL_DOWN);
   }

   if (menu_input_mouse_state(MENU_MOUSE_WHEEL_UP))
   {
      BIT64_SET(*input_mouse, MENU_MOUSE_ACTION_WHEEL_UP);
   }

   if (menu_input_mouse_state(MENU_MOUSE_HORIZ_WHEEL_DOWN))
   {
      BIT64_SET(*input_mouse, MENU_MOUSE_ACTION_HORIZ_WHEEL_DOWN);
   }

   if (menu_input_mouse_state(MENU_MOUSE_HORIZ_WHEEL_UP))
   {
      BIT64_SET(*input_mouse, MENU_MOUSE_ACTION_HORIZ_WHEEL_UP);
   }

   return 0;
}
Beispiel #26
0
static void parport_poll_pad(struct parport_joypad *pad)
{
   /* RetroArch uses an extended version of the Linux
   * Multisystem 2-button joystick protocol for parallel port
   * joypads:
   *
   * | Function    | Pin | Register | Bit | Active |
   * |-------------|-----|----------|-----|--------|
   * | Up          | 2   | Data     | 0   | Low    |
   * | Down        | 3   | Data     | 1   | Low    |
   * | Left        | 4   | Data     | 2   | Low    |
   * | Right       | 5   | Data     | 3   | Low    |
   * | A           | 6   | Data     | 4   | Low    |
   * | B           | 7   | Data     | 5   | Low    |
   * | Start       | 8   | Data     | 6   | Low    |
   * | Select      | 9   | Data     | 7   | Low    |
   * | Menu toggle | 10  | Status   | 6   | Low    |
   * | X           | 11  | Status   | 7   | Low*   |
   * | Y           | 12  | Status   | 5   | Low    |
   * | L1          | 13  | Status   | 4   | Low    |
   * | R1          | 15  | Status   | 3   | Low    |
   *
   * (*) Pin is hardware inverted, but RetroArch inverts it
   *     back again so the same pullup scheme may be used for
   *     all pins.
   *
   * Pin 1 is set high so it can be used for pullups.
   *
   * RetroArch does not perform debouncing, and so long as
   * the button settling time is less than the frame time
   * no bouncing will be observed. This replicates the latching
   * behavior common in old games consoles. For optimum latency
   * and jitter a high performance debouncing routine should be
   * implemented in the controller hardware.
   */

   int i;
   char data;
   char status;

   ioctl(pad->fd, PPRDATA, &data);
   ioctl(pad->fd, PPRSTATUS, &status);

   for (i = 0; i < 8; i++)
   {
      if (!(data & UINT8_C(1 << i)) && pad->button_enable[i])
         BIT64_SET(pad->buttons, i);
      else
         BIT64_CLEAR(pad->buttons, i);
   }
   for (i = 3; i < 8; i++)
   {
      if (!(status & UINT8_C(1 << i)) && pad->button_enable[i + 5])
         BIT64_SET(pad->buttons, i + 5);
      else
         BIT64_CLEAR(pad->buttons, i + 5);
   }

   if (BIT64_GET(pad->buttons, 12) && pad->button_enable[12])
      BIT64_CLEAR(pad->buttons, 12);
   else
      BIT64_SET(pad->buttons, 12);
}
Beispiel #27
0
/**
 * runloop_iterate:
 *
 * Run Libretro core in RetroArch for one frame.
 *
 * Returns: 0 on success, 1 if we have to wait until button input in order
 * to wake up the loop, -1 if we forcibly quit out of the RetroArch iteration loop.
 **/
int runloop_iterate(unsigned *sleep_ms)
{
   unsigned i;
   event_cmd_state_t    cmd;
   event_cmd_state_t   *cmd_ptr                 = &cmd;
   retro_time_t current, target, to_sleep_ms;
   static retro_usec_t frame_time_last          = 0;
   static retro_time_t frame_limit_minimum_time = 0.0;
   static retro_time_t frame_limit_last_time    = 0.0;
   static retro_input_t last_input              = 0;
   settings_t *settings                         = config_get_ptr();
   global_t   *global                           = global_get_ptr();
   rarch_system_info_t *system                  = NULL;

   cmd.state[1]                                 = last_input;
   cmd.state[0]                                 = input_keys_pressed();
   last_input                                   = cmd.state[0];

   runloop_ctl(RUNLOOP_CTL_SYSTEM_INFO_GET, &system);

   if (runloop_ctl(RUNLOOP_CTL_IS_FRAME_TIME_LAST, NULL))
   {
      frame_time_last = 0;
      runloop_ctl(RUNLOOP_CTL_UNSET_FRAME_TIME_LAST, NULL);
   }

   if (runloop_ctl(RUNLOOP_CTL_SHOULD_SET_FRAME_LIMIT, NULL))
   {
      struct retro_system_av_info *av_info = video_viewport_get_system_av_info();
      float fastforward_ratio              = (settings->fastforward_ratio == 0.0f) 
         ? 1.0f : settings->fastforward_ratio;

      frame_limit_last_time    = retro_get_time_usec();
      frame_limit_minimum_time = (retro_time_t)roundf(1000000.0f 
            / (av_info->timing.fps * fastforward_ratio));

      runloop_ctl(RUNLOOP_CTL_UNSET_FRAME_LIMIT, NULL);
   }

   if (input_driver_ctl(RARCH_INPUT_CTL_IS_FLUSHING_INPUT, NULL))
   {
      input_driver_ctl(RARCH_INPUT_CTL_UNSET_FLUSHING_INPUT, NULL);
      if (cmd.state[0])
      {
         cmd.state[0] = 0;

         /* If core was paused before entering menu, evoke
          * pause toggle to wake it up. */
         if (runloop_ctl(RUNLOOP_CTL_IS_PAUSED, NULL))
            BIT64_SET(cmd.state[0], RARCH_PAUSE_TOGGLE);
         input_driver_ctl(RARCH_INPUT_CTL_SET_FLUSHING_INPUT, NULL);
      }
   }

   if (system->frame_time.callback)
   {
      /* Updates frame timing if frame timing callback is in use by the core.
       * Limits frame time if fast forward ratio throttle is enabled. */

      bool is_slowmotion;
      retro_time_t current     = retro_get_time_usec();
      retro_time_t delta       = current - frame_time_last;
      bool is_locked_fps       = (runloop_ctl(RUNLOOP_CTL_IS_PAUSED, NULL) ||
            input_driver_ctl(RARCH_INPUT_CTL_IS_NONBLOCK_STATE, NULL)) |
         !!recording_driver_get_data_ptr();

      runloop_ctl(RUNLOOP_CTL_IS_SLOWMOTION, &is_slowmotion);

      if (!frame_time_last || is_locked_fps)
         delta = system->frame_time.reference;

      if (!is_locked_fps && is_slowmotion)
         delta /= settings->slowmotion_ratio;

      frame_time_last = current;

      if (is_locked_fps)
         frame_time_last = 0;

      system->frame_time.callback(delta);
   }

   cmd.state[2]      = cmd.state[0] & ~cmd.state[1];  /* trigger  */

   if (runloop_cmd_triggered(cmd_ptr, RARCH_OVERLAY_NEXT))
      event_command(EVENT_CMD_OVERLAY_NEXT);

   if (runloop_cmd_triggered(cmd_ptr, RARCH_FULLSCREEN_TOGGLE_KEY))
   {
      bool fullscreen_toggled = !runloop_ctl(RUNLOOP_CTL_IS_PAUSED, NULL);
#ifdef HAVE_MENU
      fullscreen_toggled = fullscreen_toggled || menu_driver_ctl(RARCH_MENU_CTL_IS_ALIVE, NULL);
#endif

      if (fullscreen_toggled)
         event_command(EVENT_CMD_FULLSCREEN_TOGGLE);
   }

   if (runloop_cmd_triggered(cmd_ptr, RARCH_GRAB_MOUSE_TOGGLE))
      event_command(EVENT_CMD_GRAB_MOUSE_TOGGLE);

#ifdef HAVE_MENU
   if (runloop_cmd_menu_press(cmd_ptr) || (global->inited.core.type == CORE_TYPE_DUMMY))
   {
      if (menu_driver_ctl(RARCH_MENU_CTL_IS_ALIVE, NULL))
      {
         if (global->inited.main && (global->inited.core.type != CORE_TYPE_DUMMY))
            rarch_ctl(RARCH_CTL_MENU_RUNNING_FINISHED, NULL);
      }
      else
         rarch_ctl(RARCH_CTL_MENU_RUNNING, NULL);
   }
#endif

#ifdef HAVE_OVERLAY
   runloop_iterate_linefeed_overlay(settings);
#endif

   if (runloop_iterate_time_to_exit(runloop_cmd_press(cmd_ptr, RARCH_QUIT_KEY)) != 1)
   {
      frame_limit_last_time = 0.0;
      return -1;
   }


#ifdef HAVE_MENU
   if (menu_driver_ctl(RARCH_MENU_CTL_IS_ALIVE, NULL))
   {
      bool focused = runloop_ctl(RUNLOOP_CTL_CHECK_FOCUS, NULL) && !ui_companion_is_on_foreground();
      bool is_idle = runloop_ctl(RUNLOOP_CTL_IS_IDLE, NULL);

      if (menu_driver_iterate((enum menu_action)menu_input_frame_retropad(cmd.state[0], cmd.state[2])) == -1)
         rarch_ctl(RARCH_CTL_MENU_RUNNING_FINISHED, NULL);

      if (focused || !is_idle)
         menu_driver_ctl(RARCH_MENU_CTL_RENDER, NULL);

      if (!focused || is_idle)
      {
         *sleep_ms = 10;
         return 1;
      }

      goto end;
   }
#endif

   if (!runloop_ctl(RUNLOOP_CTL_CHECK_STATE, &cmd))
   {
      /* RetroArch has been paused. */
      retro_ctx.poll_cb();
      *sleep_ms = 10;
      return 1;
   }

#if defined(HAVE_THREADS)
   lock_autosave();
#endif

#ifdef HAVE_NETPLAY
   netplay_driver_ctl(RARCH_NETPLAY_CTL_PRE_FRAME, NULL);
#endif

   if (bsv_movie_ctl(BSV_MOVIE_CTL_IS_INITED, NULL))
      bsv_movie_ctl(BSV_MOVIE_CTL_SET_FRAME_START, NULL);

   if (system->camera_callback.caps)
      driver_camera_poll();

   /* Update binds for analog dpad modes. */
   for (i = 0; i < settings->input.max_users; i++)
   {
      if (!settings->input.analog_dpad_mode[i])
         continue;

      input_push_analog_dpad(settings->input.binds[i],
            settings->input.analog_dpad_mode[i]);
      input_push_analog_dpad(settings->input.autoconf_binds[i],
            settings->input.analog_dpad_mode[i]);
   }

   if ((settings->video.frame_delay > 0) && 
         !input_driver_ctl(RARCH_INPUT_CTL_IS_NONBLOCK_STATE, NULL))
      retro_sleep(settings->video.frame_delay);

   /* Run libretro for one frame. */
   core.retro_run();

#ifdef HAVE_CHEEVOS
   /* Test the achievements. */
   cheevos_test();
#endif

   for (i = 0; i < settings->input.max_users; i++)
   {
      if (!settings->input.analog_dpad_mode[i])
         continue;

      input_pop_analog_dpad(settings->input.binds[i]);
      input_pop_analog_dpad(settings->input.autoconf_binds[i]);
   }

   if (bsv_movie_ctl(BSV_MOVIE_CTL_IS_INITED, NULL))
      bsv_movie_ctl(BSV_MOVIE_CTL_SET_FRAME_END, NULL);

#ifdef HAVE_NETPLAY
   netplay_driver_ctl(RARCH_NETPLAY_CTL_POST_FRAME, NULL);
#endif

#if defined(HAVE_THREADS)
   unlock_autosave();
#endif

#ifdef HAVE_MENU
end:
#endif
   if (!settings->fastforward_ratio)
      return 0;

   current                        = retro_get_time_usec();
   target                         = frame_limit_last_time + frame_limit_minimum_time;
   to_sleep_ms                    = (target - current) / 1000;

   if (to_sleep_ms > 0)
   {
      *sleep_ms = (unsigned)to_sleep_ms;
      /* Combat jitter a bit. */
      frame_limit_last_time += frame_limit_minimum_time;
      return 1;
   }

   frame_limit_last_time  = retro_get_time_usec();

   return 0;
}
Beispiel #28
0
static enum runloop_state runloop_check_state(
      settings_t *settings,
      uint64_t current_input,
      uint64_t old_input,
      unsigned *sleep_ms)
{
   static bool old_focus            = true;
#ifdef HAVE_OVERLAY
   static char prev_overlay_restore = false;
   bool osk_enable                  = input_driver_is_onscreen_keyboard_enabled();
#endif
#ifdef HAVE_NETWORKING
   bool tmp                         = false;
#endif
   bool focused                     = true;
   uint64_t trigger_input           = current_input & ~old_input;
   bool pause_pressed               = runloop_cmd_triggered(trigger_input, RARCH_PAUSE_TOGGLE);

   if (input_driver_is_flushing_input())
   {
      input_driver_unset_flushing_input();
      if (current_input)
      {
         current_input = 0;

         /* If core was paused before entering menu, evoke
          * pause toggle to wake it up. */
         if (runloop_paused)
            BIT64_SET(current_input, RARCH_PAUSE_TOGGLE);
         input_driver_set_flushing_input();
      }
   }

   if (runloop_cmd_triggered(trigger_input, RARCH_OVERLAY_NEXT))
      command_event(CMD_EVENT_OVERLAY_NEXT, NULL);

   if (runloop_cmd_triggered(trigger_input, RARCH_FULLSCREEN_TOGGLE_KEY))
   {
      bool fullscreen_toggled = !runloop_paused;
#ifdef HAVE_MENU
      fullscreen_toggled = fullscreen_toggled ||
         menu_driver_ctl(RARCH_MENU_CTL_IS_ALIVE, NULL);
#endif

      if (fullscreen_toggled)
         command_event(CMD_EVENT_FULLSCREEN_TOGGLE, NULL);
   }

   if (runloop_cmd_triggered(trigger_input, RARCH_GRAB_MOUSE_TOGGLE))
      command_event(CMD_EVENT_GRAB_MOUSE_TOGGLE, NULL);


#ifdef HAVE_OVERLAY
   if (osk_enable && !input_keyboard_ctl(
            RARCH_INPUT_KEYBOARD_CTL_IS_LINEFEED_ENABLED, NULL))
   {
      input_driver_unset_onscreen_keyboard_enabled();
      prev_overlay_restore  = true;
      command_event(CMD_EVENT_OVERLAY_DEINIT, NULL);
   }
   else if (!osk_enable && input_keyboard_ctl(
            RARCH_INPUT_KEYBOARD_CTL_IS_LINEFEED_ENABLED, NULL))
   {
      input_driver_set_onscreen_keyboard_enabled();
      prev_overlay_restore  = false;
      command_event(CMD_EVENT_OVERLAY_INIT, NULL);
   }
   else if (prev_overlay_restore)
   {
      if (!settings->input.overlay_hide_in_menu)
         command_event(CMD_EVENT_OVERLAY_INIT, NULL);
      prev_overlay_restore = false;
   }
#endif

   if (runloop_iterate_time_to_exit(
            runloop_cmd_press(current_input, RARCH_QUIT_KEY)) != 1)
      return RUNLOOP_STATE_QUIT;

#ifdef HAVE_MENU
   if (menu_driver_ctl(RARCH_MENU_CTL_IS_ALIVE, NULL))
   {
      menu_ctx_iterate_t iter;
      bool skip = false;
#ifdef HAVE_OVERLAY
      skip = osk_enable && input_keyboard_return_pressed();
#endif

      if (!skip)
      {
         enum menu_action action = (enum menu_action)menu_event(current_input, trigger_input);
         bool focused            = settings->pause_nonactive ? video_driver_is_focused() : true;

         focused                 = focused && !ui_companion_is_on_foreground();

         iter.action             = action;

         if (!menu_driver_ctl(RARCH_MENU_CTL_ITERATE, &iter))
            rarch_ctl(RARCH_CTL_MENU_RUNNING_FINISHED, NULL);

         if (focused || !runloop_idle)
            menu_driver_ctl(RARCH_MENU_CTL_RENDER, NULL);

         if (!focused)
            return RUNLOOP_STATE_SLEEP;

         if (action == MENU_ACTION_QUIT)
            return RUNLOOP_STATE_QUIT;
      }
   }
#endif
   
   if (runloop_idle)
      return RUNLOOP_STATE_SLEEP;

#ifdef HAVE_MENU
   if (menu_event_keyboard_is_set(RETROK_F1) == 1)
   {
      if (menu_driver_ctl(RARCH_MENU_CTL_IS_ALIVE, NULL))
      {
         if (rarch_ctl(RARCH_CTL_IS_INITED, NULL) &&
               !rarch_ctl(RARCH_CTL_IS_DUMMY_CORE, NULL))
         {
            rarch_ctl(RARCH_CTL_MENU_RUNNING_FINISHED, NULL);
            menu_event_keyboard_set(false, RETROK_F1);
         }
      }
   }
   else if ((!menu_event_keyboard_is_set(RETROK_F1) && runloop_cmd_menu_press(current_input, old_input, trigger_input)) ||
         rarch_ctl(RARCH_CTL_IS_DUMMY_CORE, NULL))
   {
      if (menu_driver_ctl(RARCH_MENU_CTL_IS_ALIVE, NULL))
      {
         if (rarch_ctl(RARCH_CTL_IS_INITED, NULL) &&
               !rarch_ctl(RARCH_CTL_IS_DUMMY_CORE, NULL))
            rarch_ctl(RARCH_CTL_MENU_RUNNING_FINISHED, NULL);
      }
      else
      {
        menu_display_toggle_set_reason(MENU_TOGGLE_REASON_USER);
        rarch_ctl(RARCH_CTL_MENU_RUNNING, NULL);
      }
   }
   else
      menu_event_keyboard_set(false, RETROK_F1);

   if (menu_driver_ctl(RARCH_MENU_CTL_IS_ALIVE, NULL))
   {
      if (!settings->menu.throttle_framerate && !settings->fastforward_ratio)
         return RUNLOOP_STATE_MENU_ITERATE;

      return RUNLOOP_STATE_END;
   }
#endif

   if (settings->pause_nonactive)
      focused                = video_driver_is_focused();

   if (runloop_cmd_triggered(trigger_input, RARCH_SCREENSHOT))
      command_event(CMD_EVENT_TAKE_SCREENSHOT, NULL);

   if (runloop_cmd_triggered(trigger_input, RARCH_MUTE))
      command_event(CMD_EVENT_AUDIO_MUTE_TOGGLE, NULL);

   if (runloop_cmd_triggered(trigger_input, RARCH_OSK))
   {
      if (input_keyboard_ctl(
               RARCH_INPUT_KEYBOARD_CTL_IS_LINEFEED_ENABLED, NULL))
         input_keyboard_ctl(
               RARCH_INPUT_KEYBOARD_CTL_UNSET_LINEFEED_ENABLED, NULL);
      else
         input_keyboard_ctl(
               RARCH_INPUT_KEYBOARD_CTL_SET_LINEFEED_ENABLED, NULL);
   }

   if (runloop_cmd_press(current_input, RARCH_VOLUME_UP))
      command_event(CMD_EVENT_VOLUME_UP, NULL);
   else if (runloop_cmd_press(current_input, RARCH_VOLUME_DOWN))
      command_event(CMD_EVENT_VOLUME_DOWN, NULL);

#ifdef HAVE_NETWORKING
   tmp = runloop_cmd_triggered(trigger_input, RARCH_NETPLAY_FLIP);
   netplay_driver_ctl(RARCH_NETPLAY_CTL_FLIP_PLAYERS, &tmp);
   tmp = runloop_cmd_triggered(trigger_input, RARCH_FULLSCREEN_TOGGLE_KEY);
   netplay_driver_ctl(RARCH_NETPLAY_CTL_FULLSCREEN_TOGGLE, &tmp);
#endif

   /* Check if libretro pause key was pressed. If so, pause or
    * unpause the libretro core. */

   /* FRAMEADVANCE will set us into pause mode. */
   pause_pressed |= !runloop_paused && runloop_cmd_triggered(trigger_input, RARCH_FRAMEADVANCE);

   if (focused && pause_pressed)
      command_event(CMD_EVENT_PAUSE_TOGGLE, NULL);
   else if (focused && !old_focus)
      command_event(CMD_EVENT_UNPAUSE, NULL);
   else if (!focused && old_focus)
      command_event(CMD_EVENT_PAUSE, NULL);

   old_focus = focused;

   if (!focused)
      return RUNLOOP_STATE_SLEEP;

   if (runloop_paused)
   {
      /* check pause state */

      bool check_is_oneshot = runloop_cmd_triggered(trigger_input,
            RARCH_FRAMEADVANCE)
         || runloop_cmd_press(current_input, RARCH_REWIND);
      if (runloop_cmd_triggered(trigger_input, RARCH_FULLSCREEN_TOGGLE_KEY))
      {
         command_event(CMD_EVENT_FULLSCREEN_TOGGLE, NULL);
         if (!runloop_ctl(RUNLOOP_CTL_IS_IDLE, NULL))
            video_driver_cached_frame();
      }

      if (!check_is_oneshot)
         return RUNLOOP_STATE_SLEEP;
   }

   /* To avoid continous switching if we hold the button down, we require
    * that the button must go from pressed to unpressed back to pressed
    * to be able to toggle between then.
    */
   if (runloop_cmd_triggered(trigger_input, RARCH_FAST_FORWARD_KEY))
   {
      if (input_driver_is_nonblock_state())
         input_driver_unset_nonblock_state();
      else
         input_driver_set_nonblock_state();
      driver_ctl(RARCH_DRIVER_CTL_SET_NONBLOCK_STATE, NULL);
   }
   else if ((runloop_cmd_pressed(old_input, RARCH_FAST_FORWARD_HOLD_KEY) 
         != runloop_cmd_press(current_input, RARCH_FAST_FORWARD_HOLD_KEY)))
   {
      if (runloop_cmd_press(current_input, RARCH_FAST_FORWARD_HOLD_KEY))
         input_driver_set_nonblock_state();
      else
         input_driver_unset_nonblock_state();
      driver_ctl(RARCH_DRIVER_CTL_SET_NONBLOCK_STATE, NULL);
   }

   /* Checks if the state increase/decrease keys have been pressed 
    * for this frame. */
   if (runloop_cmd_triggered(trigger_input, RARCH_STATE_SLOT_PLUS))
   {
      char msg[128];

      msg[0] = '\0';

      settings->state_slot++;

      snprintf(msg, sizeof(msg), "%s: %d",
            msg_hash_to_str(MSG_STATE_SLOT),
            settings->state_slot);

      runloop_msg_queue_push(msg, 2, 180, true);

      RARCH_LOG("%s\n", msg);
   }
   else if (runloop_cmd_triggered(trigger_input, RARCH_STATE_SLOT_MINUS))
   {
      char msg[128];

      msg[0] = '\0';

      if (settings->state_slot > 0)
         settings->state_slot--;

      snprintf(msg, sizeof(msg), "%s: %d",
            msg_hash_to_str(MSG_STATE_SLOT),
            settings->state_slot);

      runloop_msg_queue_push(msg, 2, 180, true);

      RARCH_LOG("%s\n", msg);
   }

   if (runloop_cmd_triggered(trigger_input, RARCH_SAVE_STATE_KEY))
      command_event(CMD_EVENT_SAVE_STATE, NULL);
   else if (runloop_cmd_triggered(trigger_input, RARCH_LOAD_STATE_KEY))
      command_event(CMD_EVENT_LOAD_STATE, NULL);

#ifdef HAVE_CHEEVOS
   if (!settings->cheevos.hardcore_mode_enable)
#endif
      state_manager_check_rewind(runloop_cmd_press(current_input, RARCH_REWIND));

   runloop_slowmotion = runloop_cmd_press(current_input, RARCH_SLOWMOTION);

   if (runloop_slowmotion)
   {
      /* Checks if slowmotion toggle/hold was being pressed and/or held. */
      if (settings->video.black_frame_insertion)
      {
         if (!runloop_ctl(RUNLOOP_CTL_IS_IDLE, NULL))
            video_driver_cached_frame();
      }

      if (state_manager_frame_is_reversed())
         runloop_msg_queue_push(msg_hash_to_str(MSG_SLOW_MOTION_REWIND), 2, 30, true);
      else
         runloop_msg_queue_push(msg_hash_to_str(MSG_SLOW_MOTION), 2, 30, true);
   }

   if (runloop_cmd_triggered(trigger_input, RARCH_MOVIE_RECORD_TOGGLE))
      bsv_movie_check();

   if (runloop_cmd_triggered(trigger_input, RARCH_SHADER_NEXT) ||
      runloop_cmd_triggered(trigger_input, RARCH_SHADER_PREV))
      dir_check_shader(
            runloop_cmd_triggered(trigger_input, RARCH_SHADER_NEXT),
            runloop_cmd_triggered(trigger_input, RARCH_SHADER_PREV));

   if (runloop_cmd_triggered(trigger_input, RARCH_DISK_EJECT_TOGGLE))
      command_event(CMD_EVENT_DISK_EJECT_TOGGLE, NULL);
   else if (runloop_cmd_triggered(trigger_input, RARCH_DISK_NEXT))
      command_event(CMD_EVENT_DISK_NEXT, NULL);
   else if (runloop_cmd_triggered(trigger_input, RARCH_DISK_PREV))
      command_event(CMD_EVENT_DISK_PREV, NULL);

   if (runloop_cmd_triggered(trigger_input, RARCH_RESET))
      command_event(CMD_EVENT_RESET, NULL);

   cheat_manager_state_checks(
         runloop_cmd_triggered(trigger_input, RARCH_CHEAT_INDEX_PLUS),
         runloop_cmd_triggered(trigger_input, RARCH_CHEAT_INDEX_MINUS),
         runloop_cmd_triggered(trigger_input, RARCH_CHEAT_TOGGLE));

   return RUNLOOP_STATE_ITERATE;
}
Beispiel #29
0
static int menu_input_mouse_post_iterate(uint64_t *input_mouse,
      menu_file_list_cbs_t *cbs, unsigned action)
{
   size_t selection;
   unsigned header_height;
   settings_t *settings     = config_get_ptr();
   menu_input_t *menu_input = menu_input_get_ptr();

   *input_mouse = MOUSE_ACTION_NONE;

   menu_navigation_ctl(MENU_NAVIGATION_CTL_GET_SELECTION, &selection);

   if (!settings->menu.mouse.enable
#ifdef HAVE_OVERLAY
       || (settings->input.overlay_enable && input_overlay_is_alive())
#endif
       )
   {
      menu_input->mouse.wheeldown = false;
      menu_input->mouse.wheelup   = false;
      menu_input->mouse.oldleft   = false;
      menu_input->mouse.oldright  = false;
      return 0;
   }

   if (menu_input_mouse_state(MENU_MOUSE_LEFT_BUTTON))
   {
      if (!menu_input->mouse.oldleft)
      {
         menu_display_ctl(MENU_DISPLAY_CTL_HEADER_HEIGHT, &header_height);

         BIT64_SET(*input_mouse, MOUSE_ACTION_BUTTON_L);

         menu_input->mouse.oldleft = true;

         if ((unsigned)menu_input->mouse.y < header_height)
         {
            menu_entries_pop_stack(&selection, 0);
            menu_navigation_ctl(MENU_NAVIGATION_CTL_SET_SELECTION, &selection);
            return 0;
         }
         if ((menu_input->mouse.ptr == selection) && cbs && cbs->action_select)
         {
            BIT64_SET(*input_mouse, MOUSE_ACTION_BUTTON_L_TOGGLE);
         }
         else if (menu_input->mouse.ptr <= (menu_entries_get_size() - 1))
         {
            BIT64_SET(*input_mouse, MOUSE_ACTION_BUTTON_L_SET_NAVIGATION);
         }
      }
   }
   else
      menu_input->mouse.oldleft = false;

   if (menu_input_mouse_state(MENU_MOUSE_RIGHT_BUTTON))
   {
      if (!menu_input->mouse.oldright)
      {
         menu_input->mouse.oldright = true;
         BIT64_SET(*input_mouse, MOUSE_ACTION_BUTTON_R);
      }
   }
   else
      menu_input->mouse.oldright = false;

   if (menu_input->mouse.wheeldown)
   {
      BIT64_SET(*input_mouse, MOUSE_ACTION_WHEEL_DOWN);
   }

   if (menu_input->mouse.wheelup)
   {
      BIT64_SET(*input_mouse, MOUSE_ACTION_WHEEL_UP);
   }

   return 0;
}
Beispiel #30
0
static void gx_joypad_poll(void)
{
   unsigned i, j, port;
   uint8_t gcpad    = 0;

   pad_state[0] = 0;
   pad_state[1] = 0;
   pad_state[2] = 0;
   pad_state[3] = 0;

   gcpad = PAD_ScanPads();

#ifdef HW_RVL
   WPAD_ReadPending(WPAD_CHAN_ALL, NULL);
#endif

   for (port = 0; port < MAX_PADS; port++)
   {
      uint32_t down = 0, ptype = WPAD_EXP_NOCONTROLLER;
      uint64_t *state_cur = &pad_state[port];

#ifdef HW_RVL
      if (WPADProbe(port, &ptype) == WPAD_ERR_NONE)
      {
         WPADData *wpaddata = (WPADData*)WPAD_Data(port);
         expansion_t *exp = NULL;

         down = wpaddata->btns_h;

         exp = (expansion_t*)&wpaddata->exp;

         *state_cur |= (down & WPAD_BUTTON_A) ? (UINT64_C(1) << GX_WIIMOTE_A) : 0;
         *state_cur |= (down & WPAD_BUTTON_B) ? (UINT64_C(1) << GX_WIIMOTE_B) : 0;
         *state_cur |= (down & WPAD_BUTTON_1) ? (UINT64_C(1) << GX_WIIMOTE_1) : 0;
         *state_cur |= (down & WPAD_BUTTON_2) ? (UINT64_C(1) << GX_WIIMOTE_2) : 0;
         *state_cur |= (down & WPAD_BUTTON_PLUS) ? (UINT64_C(1) << GX_WIIMOTE_PLUS) : 0;
         *state_cur |= (down & WPAD_BUTTON_MINUS) ? (UINT64_C(1) << GX_WIIMOTE_MINUS) : 0;
         *state_cur |= (down & WPAD_BUTTON_HOME) ? (UINT64_C(1) << GX_WIIMOTE_HOME) : 0;

         if (ptype != WPAD_EXP_NUNCHUK)
         {
            /* Rotated d-pad on Wiimote. */
            *state_cur |= (down & WPAD_BUTTON_UP) ? (UINT64_C(1) << GX_WIIMOTE_LEFT) : 0;
            *state_cur |= (down & WPAD_BUTTON_DOWN) ? (UINT64_C(1) << GX_WIIMOTE_RIGHT) : 0;
            *state_cur |= (down & WPAD_BUTTON_LEFT) ? (UINT64_C(1) << GX_WIIMOTE_DOWN) : 0;
            *state_cur |= (down & WPAD_BUTTON_RIGHT) ? (UINT64_C(1) << GX_WIIMOTE_UP) : 0;
         }


         if (ptype == WPAD_EXP_CLASSIC)
         {
            *state_cur |= (down & WPAD_CLASSIC_BUTTON_A) ? (UINT64_C(1) << GX_CLASSIC_A) : 0;
            *state_cur |= (down & WPAD_CLASSIC_BUTTON_B) ? (UINT64_C(1) << GX_CLASSIC_B) : 0;
            *state_cur |= (down & WPAD_CLASSIC_BUTTON_X) ? (UINT64_C(1) << GX_CLASSIC_X) : 0;
            *state_cur |= (down & WPAD_CLASSIC_BUTTON_Y) ? (UINT64_C(1) << GX_CLASSIC_Y) : 0;
            *state_cur |= (down & WPAD_CLASSIC_BUTTON_UP) ? (UINT64_C(1) << GX_CLASSIC_UP) : 0;
            *state_cur |= (down & WPAD_CLASSIC_BUTTON_DOWN) ? (UINT64_C(1) << GX_CLASSIC_DOWN) : 0;
            *state_cur |= (down & WPAD_CLASSIC_BUTTON_LEFT) ? (UINT64_C(1) << GX_CLASSIC_LEFT) : 0;
            *state_cur |= (down & WPAD_CLASSIC_BUTTON_RIGHT) ? (UINT64_C(1) << GX_CLASSIC_RIGHT) : 0;
            *state_cur |= (down & WPAD_CLASSIC_BUTTON_PLUS) ? (UINT64_C(1) << GX_CLASSIC_PLUS) : 0;
            *state_cur |= (down & WPAD_CLASSIC_BUTTON_MINUS) ? (UINT64_C(1) << GX_CLASSIC_MINUS) : 0;
            *state_cur |= (down & WPAD_CLASSIC_BUTTON_HOME) ? (UINT64_C(1) << GX_CLASSIC_HOME) : 0;
            *state_cur |= (down & WPAD_CLASSIC_BUTTON_FULL_L) ? (UINT64_C(1) << GX_CLASSIC_L_TRIGGER) : 0;
            *state_cur |= (down & WPAD_CLASSIC_BUTTON_FULL_R) ? (UINT64_C(1) << GX_CLASSIC_R_TRIGGER) : 0;
            *state_cur |= (down & WPAD_CLASSIC_BUTTON_ZL) ? (UINT64_C(1) << GX_CLASSIC_ZL_TRIGGER) : 0;
            *state_cur |= (down & WPAD_CLASSIC_BUTTON_ZR) ? (UINT64_C(1) << GX_CLASSIC_ZR_TRIGGER) : 0;

            analog_state[port][RETRO_DEVICE_INDEX_ANALOG_LEFT][RETRO_DEVICE_ID_ANALOG_X]  = WPAD_StickX(wpaddata, port, 0);
            analog_state[port][RETRO_DEVICE_INDEX_ANALOG_LEFT][RETRO_DEVICE_ID_ANALOG_Y]  = WPAD_StickY(wpaddata, port, 0);
            analog_state[port][RETRO_DEVICE_INDEX_ANALOG_RIGHT][RETRO_DEVICE_ID_ANALOG_X] = WPAD_StickX(wpaddata, port, 1);
            analog_state[port][RETRO_DEVICE_INDEX_ANALOG_RIGHT][RETRO_DEVICE_ID_ANALOG_Y] = WPAD_StickY(wpaddata, port, 1);
         }
         else if (ptype == WPAD_EXP_NUNCHUK)
         {
            /* Wiimote is held upright with nunchuk,
             * do not change d-pad orientation. */
            *state_cur |= (down & WPAD_BUTTON_UP) ? (UINT64_C(1) << GX_WIIMOTE_UP) : 0;
            *state_cur |= (down & WPAD_BUTTON_DOWN) ? (UINT64_C(1) << GX_WIIMOTE_DOWN) : 0;
            *state_cur |= (down & WPAD_BUTTON_LEFT) ? (UINT64_C(1) << GX_WIIMOTE_LEFT) : 0;
            *state_cur |= (down & WPAD_BUTTON_RIGHT) ? (UINT64_C(1) << GX_WIIMOTE_RIGHT) : 0;

            *state_cur |= (down & WPAD_NUNCHUK_BUTTON_Z) ? (UINT64_C(1) << GX_NUNCHUK_Z) : 0;
            *state_cur |= (down & WPAD_NUNCHUK_BUTTON_C) ? (UINT64_C(1) << GX_NUNCHUK_C) : 0;

            float js_mag = exp->nunchuk.js.mag;
            float js_ang = exp->nunchuk.js.ang;

            if (js_mag > 1.0f)
               js_mag = 1.0f;
            else if (js_mag < -1.0f)
               js_mag = -1.0f;

            double js_val_x = js_mag * sin(M_PI * js_ang / 180.0);
            double js_val_y = -js_mag * cos(M_PI * js_ang / 180.0);

            int16_t x = (int16_t)(js_val_x * 32767.0f);
            int16_t y = (int16_t)(js_val_y * 32767.0f);

            analog_state[port][RETRO_DEVICE_INDEX_ANALOG_LEFT][RETRO_DEVICE_ID_ANALOG_X] = x;
            analog_state[port][RETRO_DEVICE_INDEX_ANALOG_LEFT][RETRO_DEVICE_ID_ANALOG_Y] = y;

         }
      }
      else
#endif
      {
         if (gcpad & (1 << port))
         {
            int16_t ls_x, ls_y, rs_x, rs_y;
            uint64_t menu_combo = 0;

            down = PAD_ButtonsHeld(port);

            *state_cur |= (down & PAD_BUTTON_A) ? (UINT64_C(1) << GX_GC_A) : 0;
            *state_cur |= (down & PAD_BUTTON_B) ? (UINT64_C(1) << GX_GC_B) : 0;
            *state_cur |= (down & PAD_BUTTON_X) ? (UINT64_C(1) << GX_GC_X) : 0;
            *state_cur |= (down & PAD_BUTTON_Y) ? (UINT64_C(1) << GX_GC_Y) : 0;
            *state_cur |= (down & PAD_BUTTON_UP) ? (UINT64_C(1) << GX_GC_UP) : 0;
            *state_cur |= (down & PAD_BUTTON_DOWN) ? (UINT64_C(1) << GX_GC_DOWN) : 0;
            *state_cur |= (down & PAD_BUTTON_LEFT) ? (UINT64_C(1) << GX_GC_LEFT) : 0;
            *state_cur |= (down & PAD_BUTTON_RIGHT) ? (UINT64_C(1) << GX_GC_RIGHT) : 0;
            *state_cur |= (down & PAD_BUTTON_START) ? (UINT64_C(1) << GX_GC_START) : 0;
            *state_cur |= (down & PAD_TRIGGER_Z) ? (UINT64_C(1) << GX_GC_Z_TRIGGER) : 0;
            *state_cur |= ((down & PAD_TRIGGER_L) || PAD_TriggerL(port) > 127) ? (UINT64_C(1) << GX_GC_L_TRIGGER) : 0;
            *state_cur |= ((down & PAD_TRIGGER_R) || PAD_TriggerR(port) > 127) ? (UINT64_C(1) << GX_GC_R_TRIGGER) : 0;

            ls_x = (int16_t)PAD_StickX(port) * 256;
            ls_y = (int16_t)PAD_StickY(port) * -256;
            rs_x = (int16_t)PAD_SubStickX(port) * 256;
            rs_y = (int16_t)PAD_SubStickY(port) * -256;

            analog_state[port][RETRO_DEVICE_INDEX_ANALOG_LEFT][RETRO_DEVICE_ID_ANALOG_X] = ls_x;
            analog_state[port][RETRO_DEVICE_INDEX_ANALOG_LEFT][RETRO_DEVICE_ID_ANALOG_Y] = ls_y;
            analog_state[port][RETRO_DEVICE_INDEX_ANALOG_RIGHT][RETRO_DEVICE_ID_ANALOG_X] = rs_x;
            analog_state[port][RETRO_DEVICE_INDEX_ANALOG_RIGHT][RETRO_DEVICE_ID_ANALOG_Y] = rs_y;

            menu_combo = (UINT64_C(1) << GX_GC_START) | (UINT64_C(1) << GX_GC_Z_TRIGGER) |
               (UINT64_C(1) << GX_GC_L_TRIGGER) | (UINT64_C(1) << GX_GC_R_TRIGGER);

            if ((*state_cur & menu_combo) == menu_combo)
               *state_cur |= (UINT64_C(1) << GX_WIIMOTE_HOME);

            ptype = WPAD_EXP_GAMECUBE;
         }
#ifdef HAVE_LIBSICKSAXIS
         else
         {
            USB_DeviceChangeNotifyAsync(USB_CLASS_HID, change_cb, (void*)&lol);

            if (ss_is_connected(&dev[port]))
            {
               ptype = WPAD_EXP_SICKSAXIS;
               *state_cur |= (dev[port].pad.buttons.PS)       ? (UINT64_C(1) << RARCH_MENU_TOGGLE) : 0;
               *state_cur |= (dev[port].pad.buttons.cross)    ? (UINT64_C(1) << RETRO_DEVICE_ID_JOYPAD_B) : 0;
               *state_cur |= (dev[port].pad.buttons.square)   ? (UINT64_C(1) << RETRO_DEVICE_ID_JOYPAD_Y) : 0;
               *state_cur |= (dev[port].pad.buttons.select)   ? (UINT64_C(1) << RETRO_DEVICE_ID_JOYPAD_SELECT) : 0;
               *state_cur |= (dev[port].pad.buttons.start)    ? (UINT64_C(1) << RETRO_DEVICE_ID_JOYPAD_START) : 0;
               *state_cur |= (dev[port].pad.buttons.up)       ? (UINT64_C(1) << RETRO_DEVICE_ID_JOYPAD_UP) : 0;
               *state_cur |= (dev[port].pad.buttons.down)     ? (UINT64_C(1) << RETRO_DEVICE_ID_JOYPAD_DOWN) : 0;
               *state_cur |= (dev[port].pad.buttons.left)     ? (UINT64_C(1) << RETRO_DEVICE_ID_JOYPAD_LEFT) : 0;
               *state_cur |= (dev[port].pad.buttons.right)    ? (UINT64_C(1) << RETRO_DEVICE_ID_JOYPAD_RIGHT) : 0;
               *state_cur |= (dev[port].pad.buttons.circle)   ? (UINT64_C(1) << RETRO_DEVICE_ID_JOYPAD_A) : 0;
               *state_cur |= (dev[port].pad.buttons.triangle) ? (UINT64_C(1) << RETRO_DEVICE_ID_JOYPAD_X) : 0;
               *state_cur |= (dev[port].pad.buttons.L1)       ? (UINT64_C(1) << RETRO_DEVICE_ID_JOYPAD_L) : 0;
               *state_cur |= (dev[port].pad.buttons.R1)       ? (UINT64_C(1) << RETRO_DEVICE_ID_JOYPAD_R) : 0;
               *state_cur |= (dev[port].pad.buttons.L2)       ? (UINT64_C(1) << RETRO_DEVICE_ID_JOYPAD_L2) : 0;
               *state_cur |= (dev[port].pad.buttons.R2)       ? (UINT64_C(1) << RETRO_DEVICE_ID_JOYPAD_R2) : 0;
               *state_cur |= (dev[port].pad.buttons.L3)       ? (UINT64_C(1) << RETRO_DEVICE_ID_JOYPAD_L3) : 0;
               *state_cur |= (dev[port].pad.buttons.R3)       ? (UINT64_C(1) << RETRO_DEVICE_ID_JOYPAD_R3) : 0;
            }
            else
            {
               if (ss_open(&dev[port]) > 0)
               {
                  ptype = WPAD_EXP_SICKSAXIS;
                  ss_start_reading(&dev[port]);
                  ss_set_removal_cb(&dev[port], removal_cb, (void*)1);
               }
            }
         }
#endif
      }

      if (ptype != pad_type[port])
         handle_hotplug(port, ptype);

      for (i = 0; i < 2; i++)
         for (j = 0; j < 2; j++)
            if (analog_state[port][i][j] == -0x8000)
               analog_state[port][i][j] = -0x7fff;
   }

   uint64_t *state_p1        = &pad_state[0];


   BIT64_CLEAR(lifecycle_state, RARCH_MENU_TOGGLE);

   if (g_menu)
   {
      *state_p1 |= (UINT64_C(1) << GX_WIIMOTE_HOME);
      g_menu = false;
   }

   if (*state_p1 & ((UINT64_C(1) << GX_WIIMOTE_HOME)
#ifdef HW_RVL
            | (UINT64_C(1) << GX_CLASSIC_HOME)
#endif
            ))
      BIT64_SET(lifecycle_state, RARCH_MENU_TOGGLE);
}