cpp - SDL_JOYHATMOTION отличается при использовании Windows? - PullRequest
0 голосов
/ 30 июня 2018

Я использую SDL2 в моей программе.

Геймпад инициализируется с помощью:

SDL_Joystick* Pad1 = NULL;

Pad1 = SDL_JoystickOpen( 0 ); 

В мою функцию обработки событий я включил эту вещь:

 switch( event.type ){
 //Button-Event, as an example:
    case SDL_JOYBUTTONDOWN:
        //printf("Button: %d", event.jbutton.button, " ");
        if(event.jbutton.button==ControllP1.MoveLeftButton)
            MoveLeft=true;
 //lot of other cases

        case SDL_JOYHATMOTION:
            if(event.jhat.value==SDL_HAT_UP){MoveUp=true;MoveLeft=false; MoveRight=false; MoveDown=false;}
            if(event.jhat.value==SDL_HAT_DOWN){MoveDown=true;MoveUp=false; MoveLeft=false; MoveRight=false;}
            if(event.jhat.value==SDL_HAT_LEFT){MoveLeft=true; MoveDown=false; MoveUp=false; MoveRight=false;}
            if(event.jhat.value==SDL_HAT_RIGHT){MoveRight=true;MoveDown=false; MoveUp=false; MoveLeft=false; }
            if(event.jhat.value==SDL_HAT_CENTERED){MoveDown=false; MoveUp=false; MoveLeft=false; MoveRight=false;}
            if(event.jhat.value==SDL_HAT_LEFTUP){MoveDown=false; MoveUp=true; MoveLeft=true; MoveRight=false;}
            if(event.jhat.value==SDL_HAT_RIGHTUP){MoveDown=false; MoveUp=true; MoveLeft=false; MoveRight=true;}
            if(event.jhat.value==SDL_HAT_RIGHTDOWN){MoveDown=true; MoveUp=false; MoveLeft=false; MoveRight=true;}
            if(event.jhat.value==SDL_HAT_LEFTDOWN){MoveDown=true; MoveUp=false; MoveLeft=true; MoveRight=false;}
            break;

Обратите внимание, что этот код не предназначен только для указанного пэда, но должен реагировать на ввод на любом геймпаде.

В OpenSuse / Linux это нормально. Как только я использую Шляпу на любом Геймпаде, это вызывает событие. Однако это не работает для окон. Остальная часть кода выполняется по назначению (включая указанные события оси, кнопки и т. Д.), Но использование Hat не вызывает никакой реакции. Что является причиной этого? Нужно ли указывать геймпад при использовании SDL2 под Windows?

Спасибо и привет, мамочка

Edit1: Занимаясь серфингом, я, вероятно, нашел объяснение своей проблемы: https://forums.libsdl.org/viewtopic.php?p=39991 Я полагаю, что DPAD определяется не как HAT, а как Analog-Stick под Windows при использовании Joystick-API?

Edit2: Это была ошибка в SDL2.dll на Windows-машине, которую я использовал для тестирования. Замена SDL2.dll на новую решила проблему, шляпы реагируют так, как задумано :) Спасибо за помощь, ребята, приятно узнать об GameController-API.

Ответы [ 2 ]

0 голосов
/ 01 июля 2018

Я обновил SDL2 на целевой машине Windows - и все работает так, как задумано. Код в порядке.

Спасибо за помощь всем, приятно узнать о GameController-API.

0 голосов
/ 01 июля 2018

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 это не сработало).

...