tl; dr: В Windows у вас могут быть проблемы с драйверами, если ваше устройство странное, и вы можете использовать API-интерфейс gamecontroller, если вы ориентируетесь на игровые планшеты, поскольку это дает вам более согласованный интерфейс для использования.
Mumbo: The hat got usually the form of a cross (or a circle with a cross-form ontop). You can usually find it on the left side of your gamepad
То есть вы имеете в виду DPAD .
Во-первых, API-интерфейс джойстика от SDL находится на более низком уровне, он обрабатывает такие вещи, как настоящие джойстики , рулевые колеса и (в вашем случае) геймпады, неотличимые от устройства. Это означает, что API может быть непоследовательным на разных устройствах, например, две разные игровые панели могут отображать кнопку на разные индексы.
Хотя я думаю, что джойхаты могут всегда отображаться на DPAD в более распространенных устройствах, другие кнопки могут этого не делать (триггеры, x, y, a, b звездочка, круг и т. Д.). Приходите GamePadController, чтобы сэкономить время, что дает вам более последовательный способ управления контроллером (предоставляя вам геймпад, похожий на Xbox 360, и базу данных сопоставлений для нескольких устройств).
В исходном дереве SDL есть база данных контроллеров, которую вы можете загрузить (или загружается по умолчанию, я не проверял), вы также можете проверить эту ссылку , где, я думаю, есть другая база данных отображений для всех видов контроллеров, которые вы можете загрузить в свою программу вручную.
В этом примере используется API GameController вместо JoyStick API и печатается значение при нажатии DPAD. Я сделал тест только на Linux, может запрыгнуть на Windows позже, чтобы попробовать.
#include <SDL2/SDL.h>
#include <SDL2/SDL_image.h>
#include <thread>
#define HEIGHT 600
#define WIDTH 800
using namespace std;
int main() {
SDL_Init(SDL_INIT_VIDEO | SDL_INIT_GAMECONTROLLER);
SDL_Window *window = SDL_CreateWindow("Test", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, WIDTH, HEIGHT, SDL_WINDOW_SHOWN);
SDL_Event event;
SDL_GameController *controller = SDL_GameControllerOpen(0);
bool quit = false;
//SDL_Joystick *joy = SDL_GameControllerGetJoystick(controller);
while (!quit) {
while (SDL_PollEvent(&event)) {
if (event.type == SDL_QUIT) {
quit = true;
}
if (event.type == SDL_CONTROLLERBUTTONDOWN || event.type == SDL_CONTROLLERBUTTONUP) {
SDL_ControllerButtonEvent ev = event.cbutton;
if (ev.button == SDL_CONTROLLER_BUTTON_DPAD_DOWN)
printf("SDL_DPAD_HAT_DOWN_UP\n");
if (ev.button == SDL_CONTROLLER_BUTTON_DPAD_UP)
printf("SDL_DPAD_HAT_UP_UP\n");
if (ev.button == SDL_CONTROLLER_BUTTON_DPAD_RIGHT)
printf("SDL_DPAD_HAT_RIGHT_UP\n");
if (ev.button == SDL_CONTROLLER_BUTTON_DPAD_LEFT)
printf("SDL_DPAD_HAT_LEFT_UP\n");
}
if (event.type == SDL_CONTROLLERBUTTONDOWN) { puts ("DPAD DOWN STATE"); }
}
std::this_thread::sleep_for(std::chrono::milliseconds{33});
}
SDL_DestroyWindow(window);
SDL_Quit();
return 0;
}
С другой стороны, у вас могут быть проблемы с ДРАЙВЕРОМ (не редкость в окнах с контроллерами rando) или в случае с геймпадом, который еще не отображен. (Я попробовал Linux с контроллером PS4, и он работал правильно, но с дешевым подделкой контроллера PS2 это не сработало).