ОС и реализация независимого доступа к клавиатуре?
Я сделал FPS-игру для MSVC++, которая отлично работает на Windows. Но теперь я пытаюсь сделать его переносимым (по крайней мере, я хочу создать версию для Linux и Windows), поэтому я решил изменить IDE на Code::Blocks, а среду - на wxWidgets. Но кажется, что коды виртуальных клавиш и коды сканирования различны в разных системах.
Ранее я обнаружил, что виртуальные коды клавиш могут отличаться даже на одной и той же операционной системе, но на разных компьютерах (я получал сообщения об ошибках о том, что они не могут управлять символом (в зависимости от состояния numlock, lol, not joke), что исправляется при изменении код для использования сканкодов вместо кодов virtkey) (править: с помощью wxWidgets и коды virtkey, и коды сканирования на цифровой клавиатуре имеют разные значения в зависимости от состояния numlock, взрыв!)
Теперь с wxWidgets кажется, что wxKeyEvent::GetRawKeyCode и код, полученный ранее из lParam WM_KEYDOWN, отличаются. И я также получаю совершенно другой код сканирования в Linux (Ubuntu) от GetRawKeyCode.
Ну, я могу создать свою собственную таблицу кодов сканирования, нажав все клавиши и посмотрев, какой код он дает, но единственная проблема, которую ubuntu запускает на моем ноутбуке, а на ноутбуке нет полноценной клавиатуры... Но мне нужны все из них заставить работать настройки управления.
Итак, вопрос: есть ли стандартный и кроссплатформенный способ получить один и тот же код для одного и того же ключа (точнее, ключа в той же позиции)? (по крайней мере, на Windows и Linux)
5 ответов
Если вы еще не рассматривали это, вы можете использовать SDL.
Возможно, я неверно оцениваю то, что вы видите здесь, но просмотр исходного кода ключа приведет к различиям в аппаратном обеспечении, операционной системе, конфигурации и платформе, поэтому вам следует обратить внимание на виртуальный код ключа, возвращаемый событием ключа.
РЕДАКТИРОВАТЬ: Может быть, wxWidgets просто не справляется с этим правильно (сомнительно). Проблема с ключом numlock заключается в том, чтобы "заставить" вас обойти это (плохо) с помощью необработанного кода сканирования.
Если это так, вам не нужно выбрасывать то, что вы сделали, но если вы добавите SDL только для ввода данных, вы найдете вызовы, которые возвращают SDL_keysym, а не просто возвращают аппаратный скан-код (который вы можете ничего не делать с "исправлением"), но также сопоставьте его с символом Unicode и виртуальным символом, что, я думаю, то, что вы ищете. Надеюсь, их звонки не имеют этой проблемы с модификатором numlock.
Мое мнение таково, что совершенно неправильно использовать wxWidgets для кодирования быстро развивающихся 3D-игр. При разработке "хардкорных" игр вы должны использовать ее для разработки вспомогательных инструментов, таких как редакторы и конвертеры.
SDL это путь. Это может показаться довольно простым, но как только вы начнете жертвовать маленькими детьми нечестивым богам SDL, такие вещи, как SDL_image (идеально подходит для чтения многочисленных форматов файлов изображений - в той степени, в которой я иногда использую SDL исключительно для чтения, например, JPEG) или SDL_mixer (единственное решение вам нужно для чтения и воспроизведения основного аудио - OGG, WAV, ...).
Так что смотрите не дальше, чем SDL. Даже поддержка 2D-графики хороша, как только вы начнете использовать SDL_gfx. Сначала SDL может показаться базовым, но как только вы подсчитаете все дополнительные библиотеки, построенные вокруг него, и, как только вы закодируете несколько оберток вокруг него, вы увидите, что SDL - это идеальный баланс между необходимостью и простотой расширенного использования.
Я буду рад помочь вам с SDL, так как я нахожу это потрясающим.
Будучи FPS, используемый вами низкоуровневый графический инструментарий имеет огромное значение (я предполагаю, что вы не пишете трехмерную графику в wxWidgets). Если вы используете OpenGL, вы смотрели, что может сделать GLUT?
GlutKeyboardFunc и glutSpecialFunc в сочетании с glutGetModifiers могут быть достаточными для кроссплатформенного кода клавиатуры, а GLUT может даже использоваться для других устройств ввода.
Честно говоря, я до сих пор не понимаю, как это может иметь какое-либо отношение к wxWidgets.
Если вы не хотите использовать SDL, я рекомендую SFML - простую и быструю мультимедийную библиотеку. Это мультиплатформенный и действительно простой в использовании. Например, из раздела учебных пособий:
bool LeftKeyDown = Input.IsKeyDown(sf::Key::Left);
bool RightButtonDown = Input.IsMouseButtonDown(sf::Mouse::Right);
bool Joy0Button1Down = Input.IsJoystickButtonDown(0, 1);
unsigned int MouseX = Input.GetMouseX();
unsigned int MouseY = Input.GetMouseY();
float Joystick1X = Input.GetJoystickAxis(1, sf::Joy::AxisX);
float Joystick1Y = Input.GetJoystickAxis(1, sf::Joy::AxisY);
float Joystick1POV = Input.GetJoystickAxis(1, sf::Joy::AxisPOV);
где ввод
const sf::Input& Input = App.GetInput();
Есть некоторые признаки того, что SFML быстрее, чем SDL, однако я склонен использовать его для быстрого и переносимого кода, поскольку мне нравится его использование больше, чем SDL.