Вы не можете выбрать более 25 тем Темы должны начинаться с буквы или цифры, могут содержать дефисы(-) и должны содержать не более 35 символов.

186 строки
5.4 KiB

  1. //
  2. // Lol Engine
  3. //
  4. // Copyright: (c) 2010-2013 Sam Hocevar <sam@hocevar.net>
  5. // This program is free software; you can redistribute it and/or
  6. // modify it under the terms of the Do What The Fuck You Want To
  7. // Public License, Version 2, as published by Sam Hocevar. See
  8. // http://www.wtfpl.net/ for more details.
  9. //
  10. #if defined HAVE_CONFIG_H
  11. # include "config.h"
  12. #endif
  13. #include <cstdlib>
  14. #if defined __CELLOS_LV2__
  15. # include <cell/pad.h>
  16. # include <cell/padfilter.h>
  17. # include <sysutil/sysutil_sysparam.h>
  18. #endif
  19. #include "core.h"
  20. #include "ps3input.h"
  21. using namespace std;
  22. namespace lol
  23. {
  24. static int const NUM_PADS = 7; /* CellPadUtil also has 7 */
  25. /*
  26. * PS3 Input implementation class
  27. */
  28. class Ps3InputData
  29. {
  30. friend class Ps3Input;
  31. #if defined __CELLOS_LV2__
  32. Array<int, Stick *> m_joysticks;
  33. vec2 mousepos;
  34. ivec3 mousebuttons;
  35. CellPadData pad_data[NUM_PADS];
  36. CellPadFilterIIRSos filter_sos[NUM_PADS][4];
  37. bool circle_validates;
  38. #endif
  39. };
  40. /*
  41. * Public Ps3Input class
  42. */
  43. Ps3Input::Ps3Input()
  44. : m_data(new Ps3InputData())
  45. {
  46. #if defined __CELLOS_LV2__
  47. int32_t ret = cellPadInit(NUM_PADS);
  48. if (ret != CELL_OK && ret != CELL_PAD_ERROR_ALREADY_INITIALIZED)
  49. {
  50. Log::Error("could not initialise PS3 pad library\n");
  51. exit(1);
  52. }
  53. int tmp;
  54. ret = cellSysutilGetSystemParamInt(
  55. CELL_SYSUTIL_SYSTEMPARAM_ID_ENTER_BUTTON_ASSIGN, &tmp);
  56. m_data->circle_validates =
  57. (ret == CELL_OK && tmp == CELL_SYSUTIL_ENTER_BUTTON_ASSIGN_CIRCLE);
  58. for (int i = 0; i < NUM_PADS; i++)
  59. for (int j = 0; j < 4; j++)
  60. cellPadFilterIIRInit(&m_data->filter_sos[i][j],
  61. CELL_PADFILTER_IIR_CUTOFF_2ND_LPF_BT_010);
  62. m_data->mousepos = vec2(320.0f, 240.0f);
  63. m_data->mousebuttons = ivec3(0, 0, 0);
  64. m_gamegroup = GAMEGROUP_BEFORE;
  65. #endif
  66. }
  67. void Ps3Input::TickGame(float seconds)
  68. {
  69. Entity::TickGame(seconds);
  70. #if defined __CELLOS_LV2__
  71. CellPadInfo2 pad_info2;
  72. int32_t ret = cellPadGetInfo2(&pad_info2);
  73. if (ret != CELL_PAD_OK)
  74. return;
  75. /* Try to detect newly connected pads. */
  76. for (int i = 0; i < NUM_PADS; i++)
  77. {
  78. if (!(pad_info2.port_status[i] & CELL_PAD_STATUS_CONNECTED))
  79. continue;
  80. bool new_stick = true;
  81. for (int j = 0; j < m_data->m_joysticks.Count(); ++j)
  82. if (m_data->m_joysticks[j].m1 == i)
  83. new_stick = false;
  84. if (new_stick)
  85. {
  86. Stick *stick = Input::CreateStick();
  87. stick->SetAxisCount(4);
  88. stick->SetButtonCount(16);
  89. m_data->m_joysticks.Push(i, stick);
  90. }
  91. }
  92. /* Update pad status */
  93. for (int i = 0; i < m_data->m_joysticks.Count(); i++)
  94. {
  95. int j = m_data->m_joysticks[i].m1;
  96. if (!(pad_info2.port_status[j] & CELL_PAD_STATUS_CONNECTED))
  97. continue;
  98. /* Propagate all buttons */
  99. uint16_t bitmap1 = m_data->pad_data[j].button[CELL_PAD_BTN_OFFSET_DIGITAL1];
  100. for (int k = 0; k < 8; k++)
  101. m_data->m_joysticks[i].m2->SetButton(k, bitmap1 & (1 << k));
  102. uint16_t bitmap2 = m_data->pad_data[j].button[CELL_PAD_BTN_OFFSET_DIGITAL2];
  103. for (int k = 0; k < 8; k++)
  104. m_data->m_joysticks[i].m2->SetButton(8 + k, bitmap2 & (1 << k));
  105. /* Get Pad status. If the data hasn't changed since the last call,
  106. * data->pad[j].len will be 0 but we carry on anyway. */
  107. ret = cellPadGetData(j, &m_data->pad_data[j]);
  108. if (ret != CELL_PAD_OK)
  109. continue;
  110. if (!(pad_info2.system_info & CELL_PAD_INFO_INTERCEPTED))
  111. {
  112. int x = m_data->pad_data[j].button[CELL_PAD_BTN_OFFSET_ANALOG_RIGHT_X];
  113. int y = m_data->pad_data[j].button[CELL_PAD_BTN_OFFSET_ANALOG_RIGHT_X + 1];
  114. int x2 = m_data->pad_data[j].button[CELL_PAD_BTN_OFFSET_ANALOG_LEFT_X];
  115. int y2 = m_data->pad_data[j].button[CELL_PAD_BTN_OFFSET_ANALOG_LEFT_X + 1];
  116. /* Propagate all axes */
  117. m_data->m_joysticks[i].m2->SetAxis(0, (x - 127) / 127.0f);
  118. m_data->m_joysticks[i].m2->SetAxis(1, (y - 127) / 127.0f);
  119. m_data->m_joysticks[i].m2->SetAxis(2, (x2 - 127) / 127.0f);
  120. m_data->m_joysticks[i].m2->SetAxis(3, (y2 - 127) / 127.0f);
  121. /* Right stick moves the mouse FIXME: deprecated */
  122. vec2 delta(4.f * (abs(x - 127) < 16 ? 0 : x - 127),
  123. -4.f * (abs(y - 127) < 16 ? 0 : y - 127));
  124. m_data->mousepos += delta * seconds;
  125. Input::SetMousePos((ivec2)m_data->mousepos);
  126. }
  127. /* L1 or R1 for mouse button FIXME: deprecated */
  128. int but = (m_data->pad_data[j].button[CELL_PAD_BTN_OFFSET_DIGITAL2]
  129. & CELL_PAD_CTRL_L1)
  130. || (m_data->pad_data[j].button[CELL_PAD_BTN_OFFSET_DIGITAL2]
  131. & CELL_PAD_CTRL_R1);
  132. if (but && !m_data->mousebuttons.x)
  133. Input::SetMouseButton(0);
  134. else if (!but && m_data->mousebuttons.x)
  135. Input::UnsetMouseButton(0);
  136. m_data->mousebuttons.x = but;
  137. }
  138. #endif
  139. }
  140. Ps3Input::~Ps3Input()
  141. {
  142. #if defined __CELLOS_LV2__
  143. for (int i = 0; i < m_data->m_joysticks.Count(); ++i)
  144. {
  145. Input::DestroyStick(m_data->m_joysticks[0].m2);
  146. }
  147. #endif
  148. delete m_data;
  149. }
  150. } /* namespace lol */