Нужна помощь в изменении кода для джойстика SDL, чтобы я мог распечатать одну вещь.

Вопрос или проблема

Я новичок в программировании и хотел попробовать использовать этот код для джойстика SDL, который я нашел на GitHub. Я пытаюсь изменить код, чтобы он выводил сообщение только при нажатии на D-pad

static void test_joystick(int joy_idx)
{
  SDL_Joystick* joy = SDL_JoystickOpen(joy_idx);
  if (!joy)
  {
    fprintf(stderr, "Невозможно открыть джойстик %d\n", joy_idx);
  }
  else
  {
    initscr();

    //cbreak();
    noecho();
    nodelay(stdscr, TRUE);
    //nonl();
    curs_set(0);

    int num_axes    = SDL_JoystickNumAxes(joy);
    if (num_axes < 0) {
      fprintf(stderr, "Невозможно получить количество осей SDL: %s\n", SDL_GetError());
      exit(EXIT_FAILURE);
    }

    int num_buttons = SDL_JoystickNumButtons(joy);
    if (num_buttons < 0) {
      fprintf(stderr, "Невозможно получить количество кнопок SDL: %s\n", SDL_GetError());
      exit(EXIT_FAILURE);
    }

    int num_hats    = SDL_JoystickNumHats(joy);
    if (num_hats < 0) {
      fprintf(stderr, "Невозможно получить количество хэтов SDL: %s\n", SDL_GetError());
      exit(EXIT_FAILURE);
    }

    int num_balls   = SDL_JoystickNumBalls(joy);
    if (num_balls < 0) {
      fprintf(stderr, "Невозможно получить количество шариков SDL: %s\n", SDL_GetError());
      exit(EXIT_FAILURE);
    }

    Sint16* axes    = calloc((size_t)num_axes,    sizeof(Sint16));
    Uint8*  buttons = calloc((size_t)num_buttons, sizeof(Uint8));
    Uint8*  hats    = calloc((size_t)num_hats,    sizeof(Uint8));
    Sint16*  balls   = calloc((size_t)num_balls,   2*sizeof(Sint16));

    int quit = 0;
    SDL_Event event;
    while(!quit)
    {
      SDL_Delay(10);

      bool something_new = FALSE;
      while (SDL_PollEvent(&event)) {
        something_new = TRUE;
        switch(event.type)
        {
          case SDL_JOYAXISMOTION:
            assert(event.jaxis.axis < num_axes);
            axes[event.jaxis.axis] = event.jaxis.value;
            break;

          case SDL_JOYBUTTONDOWN:
          case SDL_JOYBUTTONUP:
            assert(event.jbutton.button < num_buttons);
            buttons[event.jbutton.button] = event.jbutton.state;
            break;

          case SDL_JOYHATMOTION:
            assert(event.jhat.hat < num_hats);
            hats[event.jhat.hat] = event.jhat.value;
            break;

          case SDL_JOYBALLMOTION:
            assert(event.jball.ball < num_balls);
            balls[2*event.jball.ball + 0] = event.jball.xrel;
            balls[2*event.jball.ball + 1] = event.jball.yrel;
            break;

          case SDL_QUIT:
            quit = 1;
            printf("Получен прерывающий сигнал, выход\n");
            break;

          default:
            fprintf(stderr, "Ошибка: Необработанный тип события: %d\n", event.type);
        }
      }

      if (something_new)
      {
        //clear();
        move(0,0);

        printw("Имя джойстика:   '%s'\n", SDL_JoystickName(joy));
        printw("Номер джойстика: %d\n", joy_idx);
        printw("\n");

        printw("Оси %2d:\n", num_axes);
        for(int i = 0; i < num_axes; ++i)
        {
          int len = COLS - 20;
          printw("  %2d: %6d  ", i, axes[i]);
          print_bar((axes[i] + 32767) * (len-1) / 65534, len);
          addch('\n');
        }
        printw("\n");

        printw("Кнопки %2d:\n", num_buttons);
        for(int i = 0; i < num_buttons; ++i)
        {
          printw("  %2d: %d  %s\n", i, buttons[i], buttons[i] ? "[#]":"[ ]");
        }
        printw("\n");

        printw("Хэты %2d:\n", num_hats);
        for(int i = 0; i < num_hats; ++i)
        {
          printw("  %2d: значение: %d\n", i, hats[i]);
          printw("  +-----+  вверх:    %c\n"
                 "  |%c %c %c|  вниз:  %c\n"
                 "  |%c %c %c|  влево:  %c\n"
                 "  |%c %c %c|  вправо: %c\n"
                 "  +-----+\n",

                 (hats[i] & SDL_HAT_UP)?'1':'0',

                 ((hats[i] & SDL_HAT_UP) && (hats[i] & SDL_HAT_LEFT)) ? 'O' : ' ',
                 ((hats[i] & SDL_HAT_UP) && !(hats[i] & (SDL_HAT_LEFT | SDL_HAT_RIGHT))) ? 'O' : ' ',
                 ((hats[i] & SDL_HAT_UP) && (hats[i] & SDL_HAT_RIGHT)) ? 'O' : ' ',

                 (hats[i] & SDL_HAT_DOWN)?'1':'0',

                 (!(hats[i] & (SDL_HAT_UP | SDL_HAT_DOWN)) && (hats[i] & SDL_HAT_LEFT)) ? 'O' : ' ',
                 (!(hats[i] & (SDL_HAT_UP | SDL_HAT_DOWN)) && !(hats[i] & (SDL_HAT_LEFT | SDL_HAT_RIGHT))) ? 'O' : ' ',
                 (!(hats[i] & (SDL_HAT_UP | SDL_HAT_DOWN)) && (hats[i] & SDL_HAT_RIGHT)) ? 'O' : ' ',

                 (hats[i] & SDL_HAT_LEFT)?'1':'0',

                 ((hats[i] & SDL_HAT_DOWN) && (hats[i] & SDL_HAT_LEFT)) ? 'O' : ' ',
                 ((hats[i] & SDL_HAT_DOWN) && !(hats[i] & (SDL_HAT_LEFT | SDL_HAT_RIGHT))) ? 'O' : ' ',
                 ((hats[i] & SDL_HAT_DOWN) && (hats[i] & SDL_HAT_RIGHT)) ? 'O' : ' ',

                 (hats[i] & SDL_HAT_RIGHT)?'1':'0');
        }
        printw("\n");

        printw("Шарики %2d: ", num_balls);
        for(int i = 0; i < num_balls; ++i)
        {
          printw("  %2d: %6d %6d\n", i, balls[2*i+0], balls[2*i+1]);
        }
        printw("\n");
        printw("\n");
        printw("Нажмите Ctrl-c для выхода\n");

        refresh();
      }

      if ( getch() == 3 ) // Ctrl-c
      {
        quit = 1;
      }
    } // while

    free(balls);
    free(hats);
    free(buttons);
    free(axes);

    endwin();
  }
}

Вот ссылка на весь код, если это поможет: https://github.com/Grumbel/sdl-jstest.git
Я просто хочу вывести SDL_JOYHATMOTION в терминал.

Я надеюсь, что это будет выведено в терминал, вместо этого:
введите описание изображения здесь

Ответ или решение

Чтобы модифицировать код SDL для печати сообщения только при нажатии на D-pad (или "кнопку-хат") джойстика, вам необходимо внести несколько изменений в функции обработки событий в вашем коде. Я предоставлю вам подробные шаги, а также измененный код.

Изменения в коде

  1. Удаление ненужной информации: Вам не нужно печатать всю информацию о джойстике. Вместо этого мы сосредоточимся на обработке событий, связанных только с D-pad.

  2. Добавление вывода сообщений для D-pad: Вам необходимо добавить соответствующий вывод для события SDL_JOYHATMOTION.

Обновленный код

Вот измененная версия вашего кода, которая удовлетворяет указанным требованиям:

#include <SDL2/SDL.h>
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <ncurses.h>

static void test_joystick(int joy_idx)
{
    SDL_Joystick* joy = SDL_JoystickOpen(joy_idx);
    if (!joy)
    {
        fprintf(stderr, "Unable to open joystick %d\n", joy_idx);
        return; // Закрываем функцию, если не удалось открыть джойстик
    }

    initscr();
    noecho();
    nodelay(stdscr, TRUE);
    curs_set(0);

    int num_hats = SDL_JoystickNumHats(joy);
    if (num_hats < 0) {
        fprintf(stderr, "Unable to get SDL hats count: %s\n", SDL_GetError());
        exit(EXIT_FAILURE);
    }

    Uint8* hats = calloc((size_t)num_hats, sizeof(Uint8));

    int quit = 0;
    SDL_Event event;

    while (!quit)
    {
        SDL_Delay(10);

        while (SDL_PollEvent(&event)) {
            switch (event.type)
            {
                case SDL_JOYHATMOTION:
                    assert(event.jhat.hat < num_hats);
                    hats[event.jhat.hat] = event.jhat.value;

                    // Печатаем сообщение о состоянии D-pad
                    printw("D-pad state changed: %d\n", hats[event.jhat.hat]);
                    refresh(); // Обновляем окно ncurses
                    break;

                case SDL_QUIT:
                    quit = 1;
                    printf("Received interrupt, exiting\n");
                    break;

                default:
                    // Не обрабатываем другие события
                    break;
            }
        }

        if (getch() == 3) // Ctrl-c
        {
            quit = 1;
        }
    }

    free(hats);
    endwin();
}

Объяснение изменений

  1. Удаление ненужной информации: Все части кода, связанного с осями и кнопками, были удалены, так как они не соответствуют вашей цели. Мы оставили только обработку D-pad.

  2. Вывод сообщения: Теперь, когда D-pad изменяет свое состояние, программа отвечает, выводя состояние (например, значение D-pad).

  3. Упрощение: Мы упростили цикл обработки событий, чтобы он сосредоточился на событии SDL_JOYHATMOTION. Это делает код более лаконичным и легким для понимания, особенно для начинающих программистов.

Заключение

Теперь программа будет выводить на терминал только информацию о состоянии D-pad при его изменении. Убедитесь, что у вас установлена библиотека SDL и компилируйте код с нужными флагами. Если у вас есть дополнительные вопросы или вам нужна помощь с установкой, не стесняйтесь обращаться.

Этот подход не только улучшит вашу практику программирования, но и позволит сосредоточиться на том, как события обрабатываются в SDL. Успехов вам в ваших усилиях!

Оцените материал
Добавить комментарий

Капча загружается...