LINUX.ORG.RU

SDL2 и события.

 , , ,


0

1

Нашел на форуме пример «нормальной» обработки клавиатурных событий. http://www.gamedev.net/topic/452938-sdl-multiple-key-press-events/

#include <stdio.h>
#include <stdlib.h>
#include <SDL2/SDL.h>
SDL_Event event;
SDL_Window *win;
int app_running;
int key[500];
//Прототипы функций
void test_func(void);
void test_func2(void);
void test_func3(void);
void key_press(int key, void (*ptr)(void));
void key_listing(void);
//Листаем события
void key_listing()
{
  if (SDL_PollEvent(&event))
     {
        //Выход по крестику
        if (event.type == SDL_QUIT) app_running=0;
        //"Нажатие" клавиши
        if (event.type == SDL_KEYDOWN) key[event.key.keysym.sym]=1; //Статус "Нажато"
        //"Поднятие" клавиши
        if (event.type == SDL_KEYUP) key[event.key.keysym.sum]=0; //Статус "НЕ нажато"
     }
}
//Передаем в функцию код клавиши (keyi) и адрес на функцию
void key_press(int keyi, void (*ptr)(void))
{
  
  if (key[keyi]) ptr; //Точно не помню, верно ли это, но, если зажатая клавиша имеет состояние 1, то выполняется функция ptr
}
//Тестовые функции, меняем заголовок окна
void test_func()
{
  SDL_SetWindowTitle(win, ".");
}
void test_func2()
{
  SDL_SetWindowTitle(win, "..");
}
void test_func3()
{
  SDL_SetWindowTitle(win, "...");
} 
int main(int argc, char **argv)
{
  app_running = 1;
  win = SDL_CreateWindow("Window",SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 640, 380, 0);
  while(__app_running)
  {
    key_liting();
    //Передаем функции "код" клавиши и адрес функции, которую необходимо выполнить
    key_press(SDLK_q, &test_func);
    key_press(SDLK_w, &test_func2);
    key_press(SDLK_e, &test_func3);
  }
}
Пишу не с домашнего ноута, скомпилировать сейчас не могу, но примерно все так и было описано. Здесь могут быть какие-либо ошибки (без компиляции не поймешь же ведь), но прошу на них сейчас не обращать внимания. И так, в чем вопрос? А в том, что это работает, и работает как надо, за исключением одного «но». Нет, даже двух «но». Первое - при нажатии и удерживание клавиши, которую мы определили в key_press, крестик, по которому можно кликнуть становится не доступным, т.е тупо не подсвечивается, и нажатие на него дает эффект. Становится он доступным после того, как цикл отработает весь стек запиханных в него событий (поясните, если не так). А второе - при нажатии, например, UP, DOWN, LEFT, RIGHT, а так же кнопок F1-F12, да и вообще, всех кнопок, где в SDK_keycode.h происходит *макроподстановка*(???), например
SDLK_F1 = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_F1),
При нажатии клавиши, где присутствует вот такая хрень, приложение вылетает. Т.е две проблемы: 1. Как я понял, забитие событийного стека 2. Неумение обработки всех клавиш. Мб есть другие способы решения поставленной задачи? Не важно, как, главное, чтобы в функцию можно было передавать код клавиши и адрес функции, которую нужно выполнить, если та или иная функция выполнена. Причем без использования С++ конструкций вообще.



Последнее исправление: cetjs2 (всего исправлений: 3)

Не знаю SDL, но мне вот это место не нравится:

key[event.key.keysym.sym]

У вас key массив определённого размера и вы не проверяете значение event.key.keysym.sym. Разве где-то в документации оговорено, что event.key.keysym.sym всегда < 500? Поставили бы сюда проверку.

mky ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.