samstyle / Xpeccy

Multiplatform emulator of retro computers
MIT License
71 stars 13 forks source link

переходы между расширенными (двойными) клавишами - shift отпускается, и вообще клавиатура странно работает #38

Closed Volutar closed 5 years ago

Volutar commented 5 years ago

Замечено, когда жмёшь например влево, а потом резко переходишь на клавишу вправо, на какое-то время shift исчезает (если смотреть на Zx keyboard), и начинают идти цифры 8.

Дело в том, что в этот небольшой промежуток перехода между нажатыми клавишами, когда они обе нажаты, капс считается зажатым один раз, и при отпускании одной из клавиш - пропадает. Хотя должен оставаться, т.к. вторая клавиша тоже с капсом. В реальности капс восстанавливается, но поздно, цифры уже во всю набираются. Более того, если не отпуская давить капс на клавиатуре и тыкать влево-вправо - капс будет всё равно пропадать!!! То же самое с Symbol Shift (скобки тоже превращаются в цифры).

samstyle commented 5 years ago

Рисую ситуацию: держишь нажатой стрелку влево (CS + 5), потом нажимаешь стрелку вправо ДО ОТПУСКАНИЯ стрелки влево (CS + 8), затем отпускаешь стрелку влево (отпускаются и CS, и 5). Итог - отпущенный CS, но зажатая 8. Мораль сей басни такова - не насилуй клавиатуру.

Volutar commented 5 years ago

Ситуация именно такая. И она должна обслуживаться корректно. С чего это CS отпускается, когда он остается зажатым другой клавишей? Получается, что CS + Left нажимаешь, отпускаешь Left, и отпускается автоматом CS, хотя физически клавиша нажата. На реальном спектруме такое прекрасно работает, потому что нет события "отпускания", транслируемого с PC.

Это не насилование клавиатуры - это типичный "быстрый набор", когда одну клавишу еще не успеваешь отпустить и нажимаешь вторую. Спектрумовский сканер клавиатуры при этом может возвращать как первую клавишу так и вторую но НИКОГДА третью (цифра в случае курсора).

samstyle commented 5 years ago

Ибо есть событие нажатия клавиши и событие отжатия клавиши. По передаваемому коду вычисляется, что должно быть нажато на zx-клавиатуре, а что отжато. Естественно, такие комбинации плохо влияют на результат.

Volutar commented 5 years ago

Дык на спектруме нету события отжатия! Это функционал эмулятора, который клавиши транслирует в двойные. И по какой-то непонятной причине вместо прямой установки значения портов клавиатуры по этим внешним событиям - транслирует это в несуществующее в zx "отпускание" двойных клавиш. В том же US таких проблем изначально не было (да и в куче других эмуляторов).

Почему меня это заботит? Я более 25 лет назад мучился из-за того что в расширенной клавиатуре периодически проскакивали цифры вместо курсора. Из-за того что код шифта появлялся уже в следущий цикл сканирования. Написал свой сканер клавиатуры который это все учитывает (использовал в PSM). Недавно обнаружил что злощасные цифры снова начали вылазить!! Попытался отдебажить - статус клавиш клавиатуры сбрасывался (создавал по этому поводу issue). И вот вчера отлаживая сканер обнаружил что это не из-за него, а из-за эмулятора, проверил в других - цифры не вылазят.

samstyle commented 5 years ago

На спектруме нету события отжатая

Наверное, потому что там контактная матрица, не? Я не про спектрум, я про Qt, который мне отсылает события "клавиша нажата" и "клавиша отжата". И по коду клавиши, передаваемому в эти события, эмулятор меняет матрицу клавиатуры ZX - устанавливает или сбрасывает биты в соотвествующих этой клавише полурядах. Варианты?

samstyle commented 5 years ago

Разве что держать список нажатых клавиш, по новому нажатию перестраивать всю матрицу с нуля, а по отжатию - удалять клавишу из этого списка и снова перестраивать. очередной гемор...

Volutar commented 5 years ago

Если так непросто перейти от событийного принципа к сканирующему - может просто считать сколько раз клавиша была нажата, и столько же раз ждать её отпускания чтобы убрать? Ведь другие эмули это как-то делают - не считают что клавиша была отпущена, если её держат другие.

Volutar commented 5 years ago

В этот же issue добавлю. Я думал что просто часть раскладки клавиш неработают (типа pgup/pgdown), но по Zx keyboard увидел что они загораются как надо. Проблема в том, что сам ZX их видит совсем не так, а именно, с какой-то третьей клавишей: кнопка (должно быть сочетание) => по факту получается тильда (cs+ss) =>cs+ss+X (а \ корректно cs+ss) вообще "`" должно бы быть cs+1 (edit) tab (cs+space) => cs+space+I [ (ss+8) =>ss+8+Y ] (ss+9) =>ss+9+U del (cs+9) =>cs+9+P home (ss+q) =>ss+q+K end (ss+e) =>ss+e+L pg up (cs+3) =>cs+3+M pg down (cs+4) =>cs+4+N

С расширенной клавиатурой странности. точка почему то в запятую превратилась делить в вопросительный знак умножить в 8 минус нормальный, а плюс вообще отсутствует. keyb_scan.sna.zip

Прикладываю снап для тестирования клавиатуры.

P.S. кастомная раскладка, как описано тут - не функционирует, невозможно сделать свою: https://github.com/samstyle/Xpeccy/blob/master/keymap

samstyle commented 5 years ago

1.Почему так происходит, я уже объяснил. Сиди и жди, пока не переделаю 2.Есть возможность создать свою карту клавиатуры, так что не надо парить мне "как должно быть" - сделай как хочешь, я сделал как удобно мне. 3.Выжал тильду - увидел как переключается курсор [K]<->[E]. Никакого X не проскакивает.

Volutar commented 5 years ago

Есть возможность создать свою карту клавиатуры, так что не надо парить мне "как должно быть" - сделай как хочешь,

Сделал. Не работает. Кастомный map выбирается, но настройки из него игнорируются полностью (может перевод строки не нравится, или пробелы/табуляции).

Выжал тильду - увидел как переключается курсор [K]<->[E]. Никакого X не проскакивает.

У людей реплицируются эти тройные. Я не просто так приложил .sna. Что-то там явно не так. Все тройные я перечислил. Остальные расширенные идут без третьей и работают как ожидается.

По первому пункту и так жду.

samstyle commented 5 years ago

Сделал. Не работает. Кастомный map выбирается, но настройки из него игнорируются полностью (может перевод строки не нравится, или пробелы/табуляции).

Потыкамши в кнопки, выяснил следующее - кеймап не применяется при запуске эмулятора. Если зайти в настройки и выжать ОК - он применится. Формат такой: PCKEY[TAB]ZXKEY1[TAB]ZXKEY2 по одной на строку. ZXKEY2 не обязателен. Названия кнопок тут - https://github.com/samstyle/Xpeccy/blob/master/keymap

У людей реплицируются эти тройные.

Тройные там в принципе невозможны, максимум 2 кнопки может нажаться. Это какие-то побочные эффекты...

samstyle commented 5 years ago

А впрочем, кеймапы я всё равно тоже буду переделывать

Volutar commented 5 years ago

Если зайти в настройки и выжать ОК - он применится. Ок, добился что действует. Но:

  • LS от RS и LC от RC - не отличаются. Qt под виндой видимо не умеет (надо как-то по-особому учить).
  • Третий код все равно вылазит. И даже четвёртый.

Тройные там в принципе невозможны, максимум 2 кнопки может нажаться. Это какие-то побочные эффекты...

Очевидно это побочные эффекты. http://volutar.myds.me/xsp_k1.mp4 Тут пробегаюсь по всем доп.клавишам. В ZX keyboard загораются 2, а в сканере - в каких-то случаях по 3. Отдельное "O" в тесте при отсутствии клавиш в Zx keyboard - это клавиша insert (когда фокус на эмуле то нет нажатия, нажатие появляется когда фокус на Zx keyboard). http://volutar.myds.me/xsp_k2.mp4 А вот тут я применил ` C 1 и вместо двух даже трёх кодов (при базовом это C+S+X, как в первом видео), стало ЧЕТЫРЕ, C+S+x+1. Ощущение, что он таблицу кодов не переписывает, а дополняет, и в дефолте там на этих доп. клавишах всякие буквы, которые при переназначении никуда не деваются, или добавляются чем-то ещё.

P.S. также не хватает возможности переназначать цифровую клавиатуру.

samstyle commented 5 years ago

Не поленился и запустил твой снапшот Debian testing: нет лишних нажатий Win 8.1 под виртуалкой: нет лишних нажатий Win 8.1 живая: нет лишних нажатий Есть одна мысля - ты используешь ПРОФИ. И "лишние" кнопки - результат скана его расширенной клавиатуры. Надо захватывать клавиатуру, чтобы эмулятор не нажимал свои комбинации и оставлял всё сугубо профи, но тогда никаких тебе CS+1 на тильде

P.S. также не хватает возможности переназначать цифровую клавиатуру.

В Qt кнопки с цифровой клавиатуры считаются за обычные с модификатором NumLock. Т.е код кнопки Enter должен быть одним и тем же и для основной клавы, и для цифровой.

Volutar commented 5 years ago

Есть одна мысля - ты используешь ПРОФИ. И "лишние" кнопки - результат скана его расширенной клавиатуры.

Да, действительно. Но дело в том, что у меня железный Профи есть, с обычной клавиатурой. И никакой подобной хрени на нём нет. Что за расширенная клавиатура? Почему это никак не конфигурится? Мне, например, никакой расширенный клавиатуры не нужно. Она скорее "ущербная" чем расширенная. Какой от неё прок в эмуляторе, где чистой ZX клавиатуры в принципе не может быть, и имеется только XT-шная?

В Qt кнопки с цифровой клавиатуры считаются за обычные с модификатором NumLock. Т.е код кнопки Enter должен быть одним и тем же и для основной клавы, и для цифровой.

Ясно. Всё бы ничего, но вот клавиша * транслируется в тупую 8, а не ss+8, а + вообще никакого кода не имеет.

ЗЫ: перевёл в Scorpion - пропали эти третьи кнопки (пентагон с глюкоромом мне не нужен, а простого 128 нету в конфигах). И всё-таки хотелось бы left/right shift/ctrl чтобы различались..

samstyle commented 5 years ago

И никакой подобной хрени на нём нет. Что за расширенная клавиатура?

В профи кнопки Delete, Insert, PageUp, PageDown итд выдают свои комбинации клавиш, только с установленным 5 битом при чтении с порта xxFE. Если не захватывать клавиатуру - и эмулятор нажимает свою комбинацию клавиш, и профи. Получается херота.

но вот клавиша * транслируется в тупую 8, а не ss+8

символ * это Shift+8, но Shift из ряда Shift+цифра исключен, потому что своим нажатием уже вызвал нажатие на zx-клаве CapsShift (по умолчанию)

а + вообще никакого кода не имеет

кнопка + это Shift и =. = вызывает SS+L, а Shift - CS. Получается ещё одна херота - CS+SS+L

Volutar commented 5 years ago

В профи кнопки Delete, Insert, PageUp, PageDown итд выдают свои комбинации клавиш, только с установленным 5 битом при чтении с порта xxFE.

Ну, у меня Профи, и клавиш delete/insert/pgup/pgdown нету, обычная матричная 40 символьная клавиатура.

Если не захватывать клавиатуру - и эмулятор нажимает свою комбинацию клавиш, и профи.

Что значит "не захватывать клавиатуру"? Это вообще легально - эмулировать одновременно обе клавиатуры? Очевидно, что при этом будет херота, если помимо обычной 40клавишной ещё и какая-то кастомная хрень эмулируется. Наверное должен быть какой-то свитч между ними двумя. Ибо к эмулю априорно подключена PC-клавиатура.

Получается ещё одна херота - CS+SS+L

Если цифровая клава хероту одну генерирует - не проще ли ее вообще "отключить", не транслировать в машину, а забиндить на служебные клавиши эмулятора, как в том же Unreal (или в тот же кемстон, например)? Неужели QT такой тупой, что не умеет хэндлить полноценную PC клаву, с левыми-правыми шифтами, и отдельными кодами для numpad?

Вообще, немного грустно что невозможно insert перебиндить (ибо на него навешен high speed).

samstyle commented 5 years ago

Неужели QT такой тупой, что не умеет хэндлить полноценную PC клаву, с левыми-правыми шифтами, и отдельными кодами для numpad?

QT - Это QuickTime А про нумпад в Qt я уже сказал - это те же самые основные клавиши с модификатором Qt::NumpadModifier

Volutar commented 5 years ago

QT - Это QuickTime

QT в этом случае это https://ru.wikipedia.org/wiki/Qt набитый в капсе.

А про нумпад в Qt я уже сказал - это те же самые основные клавиши с модификатором Qt::NumpadModifier

И получается, что этот Qt::NumpadModifier нельзя использовать для более корректной трансляции numpad keys в коды ZX? Может есть возможность получать не буквы клавиш, переконвертированные по разным раскладкам (кроме рус/анг есть еще и укр и бел и каз и куча других), а сканкоды, чтобы и левый и правый шифт отличать, обрабатывать полноценый numpad, и не зависеть от языковой раскладки? Например через nativeScanCode, где она есть. Ну а если это маке - ну что ж, если ось в плане доступа к сканкодам ущербна, то куда деваться. Благо не большинство пользователей xpeccy :). Типа как тут https://github.com/mixxxdj/mixxx/blob/master/src/controllers/keyboard/keyboardeventfilter.cpp

В крайнем случае nativeScanCode можно использовать для ДОПОЛНИТЕЛЬНОГО определения тех же left/right shift.

samstyle commented 5 years ago

QT в этом случае это https://ru.wikipedia.org/wiki/Qt набитый в капсе

учим матчасть QT - QuickTime Qt - фреймворк, о котором мы говорим

а теперь по теме: QKeyEvent::nativeScanCode возвращает разные значения в Linux и Windows, в MacOSX вообще не работает. Enum-а для этих значений не нашёл, а это значит что для каждого случая нужна своя новая таблица в где-то 100 элементов (вся клавиатура). QKeyEvent::key() работает везде, но зависит от модификаторов и раскладки клавиатуры - 1 вернёт Qt::Key_1, Shift+1 сначала вернёт Qt::Shift при нажатии Shift и Qt::Exclam ( ! ) при последующем нажатии 1. "A" в английской раскладке вернёт Qt::Key_A, в русской - код, соответствующий юникоду для буквы "Ф", енумов для не-английских букв нет

Volutar commented 5 years ago

Enum-а для этих значений не нашёл, а это значит что для каждого случая нужна своя новая таблица в где-то 100 элементов (вся клавиатура).

Наверное все же не случая, а платформы. В винде одна, в линуксе другая (наверное). В макосе- либо искать что-то нативное, либо зоопарк вариантов с key().

Вообще, как вариант, дать возможность устанавливать keymap именно в нативных сканкодах (пусть даже без названий). А таблицу с алиасами уже потом добавить. В примере кода выше в макоси key() и берётся.

Volutar commented 5 years ago

В новой сборке правые Ctrl/Shift вообще не работают и не биндятся.

samstyle commented 5 years ago

Правые специально отрезаны по умолчанию. Их можно забиндить через свой *.map. Загрузку карты клавы я тоже поправил. Плотно проблемой ещё не занимался.

Volutar commented 5 years ago

Их можно забиндить через свой *.map.

К сожалению - не очень. Если бы это сработало, я бы даже комментарий выше не написал.

samstyle commented 5 years ago

Проверил - биндятся. LS C LC S Разделитель - Tab

Volutar commented 5 years ago

Левые прекрасно биндятся. Правые не биндятся. RS S RC S

samstyle commented 5 years ago

Описька. Проверял с RS/RC. Всё равно работает. Скинь свой *.map

Volutar commented 5 years ago

Я ошибся. LS LC и RS - работают, а RC - нет. Это первое. А второе - пока не зайдёшь в настройки не нажмёшь ОК - они все не действуют. Вроде проблема давнишняя, я думал её исправили. keys.map.zip После перебиндивания такого EXT очень сложно включить. С нажатием LS, клавиша RS уже не работает, и наоборот - по отдельности работают нормально, вместе нет. Хитрым способом добиваешься залипания одной (удерживая LS нажимаешь RS, и отпускаешь LS - тогда LS остаётся залипшей), и тогда вторая может быть нажата. Такие дела. Может как то можно выводить куда-нибудь какой сканкод в событиях приходит?

samstyle commented 5 years ago

Всобачь qDebug() << kent.name << kent.key; Второй строчкой в MainWin::xkey_press в emulwin.cpp и смотри имена и коды нажатых кнопок. Что-то странное происходит, да. Даже если RS+LS сработали, следующее нажатие не срабатывает с первого раза ЗЫ: у меня ещё неделя на полную переделку клавы

samstyle commented 5 years ago

Усё понятно. Нажатия в окне клавиатуры игнорировали загруженные переопределения. В окне самого эмулятора работало. Это исправил. ЗЫ: И ещё надо выяснить коды пары клавиш в винде, потому как виртуалка их не захватывает.

Volutar commented 5 years ago

Можно было бы микроприложение сбилдить которое бы выводило и логировало кейкод и соответствующий ей нативсканкод. У меня кутэ не получилось запустить.

Усё понятно. Нажатия в окне клавиатуры игнорировали загруженные переопределения.

Вообще без разницы - открыто окно клавиатуры или нет, левые с правыми "конфликтуют" в любом случае. И мэппинг грузится только после входа в опции.

samstyle commented 5 years ago

Можно было бы микроприложение сбилдить которое бы выводило и логировало кейкод и соответствующий ей нативсканкод.

Уже сбилдено. Я же сказал - виртуалка некоторые кнопки не захватывает.

Volutar commented 5 years ago

Профи так и остаётся неюзабельным, из-за безальтернативного одновременного "сканирования" сразу двух клавиатур.

samstyle commented 5 years ago

Вобщем, как-то выкрутился. Если есть возможность собрать самому и потестить - велкам!

Volutar commented 5 years ago

Нет возможности самому собрать, к сожалению :( Спасибо. Буду ждать бинарничек.

Volutar commented 5 years ago

Протестировал.

  1. Right Ctrl вообще никак не детектится: перемапливание RC ни к чему не приводит.
  2. Одновременные нажатия LS+RS не обнаруживаются.
  3. При зажимании LC, затем RS, и отпускании LC - RS остаётся залипшим. При зажимании RS, затем LC, и отпускании RS - LC остаётся залипшим.

Залипания вообще с шифтами постоянно происходит :(

Пардон. Могу этот иссуй закрыть и сделать другой на залипания уже.

И да, профи прекрасно работает без лишних. И курсор (cs+5,6,7,8) - тоже прекрасно без отпускания переходят друг в другу :)

samstyle commented 5 years ago

Для отдельных проблем заводим отдельные темы. Эта была про отпускание нажатых два раза клавиш. PS: RC под Windows просто забыл добавить и проверить... мой косяк PS2:Комбинации RS/LS/RC/LC, возможно специфичны для Windows. Потому как под Linux ничего не залипает