BUG-KBD-5: зажатый Shift снимался автоповтором стрелки
Симптом: Shift работал в одиночку и НЕ работал вместе со стрелками — прыжок с зацепом не выходил (BUG-GRAB-1), а осторожный шаг срывался в бег. Декодеры делали из «fake shift» два вывода, и второй был неверен: обёртка E0 F0 12 / E0 12 есть -> Shift зажат -> взвести бит — верно; расширенный make БЕЗ обёртки -> Shift отпущен -> снять бит — НЕТ. Замер потока байт (MAME, breakpoint на выходе из in a,($18)): клавиатура pc_kbd ms_naturl обёртку не шлёт вовсе — при зажатом Shift поток на ↑ ровно `E0 75 E0 75 …`, ни одного F0/12. А typematic-повторы идут непрерывно, пока стрелка зажата, значит каждый повтор снимал реально зажатый Shift. Короткий тап это маскировал: после отпускания стрелки Shift снова становился последней клавишей, и его собственный автоповтор `12` взводил бит обратно за ~30 мс. Фикс: обратный вывод убран, расширенная клавиша о Shift не судит. Состояние Shift ведут его собственные make/break 12 / F0 12 — они приходят всегда. Прямой вывод оставлен (дёшев и верен там, где обёртка есть). Ушла ставшая ненужной _kbdraw_fakesh; трамплин короче на 36 Б (0x150→0x12C), что важно — его клавиатурный блок упирается в диапазон jr. Плата: потерянный при overrun break Shift снять нечем, модификатор может залипнуть до перенажатия (BUG-KBD-3). Размен решён как и раньше в kbd_raw_sync: лучше залипание, чем отвал — сорванный посреди игры Shift в PoP стоит жизни. Проверено в MAME чтением _kbdraw_down: Shift+↑+→ зажаты 5 с (автоповтор идёт) -> LSh остаётся 04; отпускание Shift -> 00. Зацеп в игре подтверждён пользователем. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
+12
-15
@@ -25,18 +25,18 @@
|
||||
* жмёт Shift+→ ожидая осторожный шаг, а Кид уходит в бег — в PoP это
|
||||
* прямо стоит жизни (яма/пики). Хуже залипания (BUG-KBD-4).
|
||||
*
|
||||
* Третий вариант убирает сам размен. Те самые лишние байты — это «fake
|
||||
* shift» (E0 F0 12 перед расширенным make, E0 12 после break), и шлются они
|
||||
* ТОЛЬКО пока Shift реально зажат. Декодеры (_irq_tramp.c, kbd_raw_poll.c)
|
||||
* теперь читают их в обе стороны: обёртка есть → Shift взвести, расширенный
|
||||
* make без обёртки → Shift снять. Значит:
|
||||
* - сбрасывать модификаторы здесь НЕ НАДО (состояние Shift подтверждается
|
||||
* независимо от того, что съел overrun);
|
||||
* - залипание невозможно: первый же тап стрелки снимет ложный Shift.
|
||||
* Выбран вариант (1) — модификаторы НЕ сбрасываем. Была и третья редакция,
|
||||
* обещавшая снять сам размен: «fake shift» (E0 F0 12 / E0 12) читался в обе
|
||||
* стороны, и расширенный make без обёртки снимал Shift, то есть залипание
|
||||
* лечилось первым же тапом стрелки. Обратный вывод оказался неверным
|
||||
* (замер 2026-08-05, BUG-GRAB-1: обёртку шлют не все клавиатуры и никогда —
|
||||
* на typematic-повторах), и он ломал Shift вместе со стрелками; убран, см.
|
||||
* _kbdraw.h. Значит размен вернулся, и здесь он решается в пользу
|
||||
* «лучше залипание, чем отвал»: залипший модификатор снимается его же
|
||||
* перенажатием, а сорванный посреди игры Shift в PoP стоит жизни.
|
||||
*
|
||||
* Ctrl/Alt fake-shift'ом не покрыты (клавиатура их не обёртывает). Их
|
||||
* оставляем по тому же принципу «лучше залипание, чем отвал»: залипший
|
||||
* Ctrl/Alt в PoP не управляет ничем критичным и снимается перенажатием.
|
||||
* Overrun теперь редок сам по себе: FIFO вычерпывается опросом из главного
|
||||
* цикла (kbd_raw_poll, KBD-1), а не только по пойманному прерыванию.
|
||||
*/
|
||||
#include <string.h>
|
||||
#include "_kbdraw.h"
|
||||
@@ -67,9 +67,6 @@ void kbd_raw_sync(void)
|
||||
if (save[i]) _kbdraw_down[c >> 3] |= (uint8_t)(1 << (c & 7));
|
||||
}
|
||||
/* FSM префиксов трамплин уже сбросил; дублируем на случай overrun'а,
|
||||
* пойманного вне его (kbd_raw_poll между кадрами). Незакрытую обёртку
|
||||
* fake shift тоже считаем недействительной: её вторая половина могла
|
||||
* пропасть вместе с потерянными байтами. */
|
||||
* пойманного вне его (kbd_raw_poll между кадрами). */
|
||||
_kbdraw_pending = 0;
|
||||
_kbdraw_fakesh = 0;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user