MAME/DEBUGGER_KEYMAP_HANDOFF.md
Tolik 6b6a5b0f9c
Some checks failed
CI (macOS) / build-macos (push) Waiting to run
CI (Windows) / build-windows (gcc, gcc-x64, g++, mame, UCRT64, windows-latest, mingw-w64-ucrt-x86_64, mame) (push) Waiting to run
Check #include guards / validate (push) Has been cancelled
Vibe changes over upstream MAME (squashed)
Содержит правки из следующих коммитов:
  - WIP: all-in-one
  - Janko: cache on
  - DeZog fix
  - Revert "drop mlz"
  - emu/debug/debugcpu.cpp,sinclair/spectrum.cpp: Guarded pointer accessors
  - sinclair/sprinter.cpp tmkonf
  - dma delay under investigation
  - harddisks-shareable.diff
  - ignore
  - плагин и скрипты для управления MAME by Claude code (MCP)
  - много всего
  - mouse release
2026-05-26 22:09:47 +10:00

171 lines
12 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Handoff: переназначаемые горячие клавиши в дебаггерах MAME
> Дай этот файл Claude в новой сессии (на другом компьютере) — он восстановит весь
> контекст задачи и сможет продолжить. Рабочая копия: `/Users/tolik/Documents/GitHub/mame`,
> ветка `Vibe`. Пользователь общается по-русски.
## Цель
Добавить в дебаггеры MAME возможность переназначать горячие клавиши с сохранением
между сессиями и UI для редактирования. Изначально просили для macOS-Cocoa-дебаггера
(`osd/modules/debugger/osx/`), затем — «для остальных дебаггеров» в
`src/osd/modules/debugger/`.
## Статус по дебаггерам
- **Cocoa (osx)** — ✅ СДЕЛАНО и собиралось (отдельная реализация на Objective-C).
- **ImGui** (`debugimgui.cpp`) — ✅ СДЕЛАНО, компилируется чисто.
- **Qt** (`debugqt.cpp` + `qt/`) — ✅ СДЕЛАНО, компилируется чисто (с `USE_QTDEBUG=1`).
- **Win** (`win/`) — ⛔ ПРОПУЩЕНО по решению пользователя (нельзя собрать/проверить на macOS;
нативный Win32-диалог — высокий риск вслепую). Не трогали.
- **gdbstub / none** — не GUI, не трогаем.
`-debugger auto` на macOS выбирает Cocoa (регистрируется первым, всегда инициализируется).
Для проверки других: `-debugger imgui -video bgfx` или `-debugger qt`.
---
## Архитектура
### Общий C++-модуль (для ImGui/Qt/Win) — НОВЫЙ
- `src/osd/modules/debugger/debugkeyconfig.h`
- `src/osd/modules/debugger/debugkeyconfig.cpp`
`namespace osd::debugger`:
- `struct key_shortcut { std::string key; bool ctrl, alt, shift; }`
`to_string()` → "Ctrl+Shift+F9" (переносимый текст), `from_string()`.
- `struct key_action { std::string id, label, group; key_shortcut default_shortcut; }`.
- `class keymap_config(std::vector<key_action>&& actions)` — хранит таблицу + overrideы:
`shortcut(id)`, `is_default`, `conflicting_action`, `set_shortcut/clear/reset/reset_all`,
`save(node)` / `load(node)` (узел `<keymap>` с дочерними `<key>`).
Каждый дебаггер задаёт СВОЮ таблицу действий (id/label/group/дефолты), а хранилище,
парсинг и XML — общие. Формат текстовый и единый → раскладка в `default.cfg` понятна
всем трём (Qt↔ImGui↔Win шарят). **Cocoa хранит в своём формате (codepoint+mask), с ним
не пересекается — это ОК (разные id, конфликтов в файле нет).**
### XML-константы (общие) — в `xmlconfig.h/.cpp`
Добавлены: `NODE_KEYMAP="keymap"`, `NODE_KEYMAP_ITEM="key"`,
`ATTR_KEYMAP_ACTION="action"`, `ATTR_KEYMAP_KEY="char"`, `ATTR_KEYMAP_MODIFIERS="modifiers"`.
(У C++-дебаггеров modifiers зашиты в текст `ATTR_KEYMAP_KEY`; у Cocoa — отдельные int.)
### Персистентность
Все дебаггеры пишут раскладку как ГЛОБАЛЬНУЮ — в `default.cfg`, через
`config_register("debugger", …)` и обработку `config_type::DEFAULT` (а не `SYSTEM`,
который для позиций окон). Сохраняются только отличия от дефолтов; пустой `<keymap>` не пишется.
---
## Что и где изменено
### Cocoa (Objective-C, отдельная реализация — НЕ использует debugkeyconfig)
НОВЫЕ:
- `osx/debugkeymap.h` / `osx/debugkeymap.mm` — синглтон `MAMEDebugKeyMap` (реестр действий,
лукапы, `applyToMenuItem:forAction:`, `refreshMenu:`, save/restore XML). Хранит unichar+mask.
- `osx/debugkeymapviewer.h` / `osx/debugkeymapviewer.mm` — окно `MAMEKeyBindingsWindow`
(таблица + запись через локальный монитор NSEvent, конфликты, Reset All).
ИЗМЕНЕНЫ:
- `osx/debugwindowhandler.{h,mm}``addCommonActionItems:` берёт клавиши из реестра;
пункт «Customize Keys…»; `showKeyBindings:`; `keyMapChanged:` рефрешит главное меню и
popup-кнопки окна; подписка на `MAMEDebugKeyMapChangedNotification`.
- `osx/disassemblyview.mm`оба построителя меню (контекст + action-button) через реестр.
- `debugosx.mm``build_menus` (главное меню Debug/Run/Step) через реестр; пункт
«Customize Keys…»; `config_load/config_save` обрабатывают `DEFAULT` для глобальной раскладки.
- `osx/debugkeymap.h` включает `"../xmlconfig.h"` (важно: с `../`, файл в подкаталоге osx/).
Идентификаторы Cocoa — camelCase ("stepInto" и т.п.).
### ImGui — `src/osd/modules/debugger/debugimgui.cpp`
- Добавлены include `debugkeyconfig.h`, `util/xmlfile.h`.
- Статическая таблица `f_imgui_keys[]` (имя↔ImGuiKey), функции `imgui_key_for_name`,
`shortcut_pressed(key_shortcut)`, `capture_shortcut(out)`.
- id-константы `IMGUI_ACT_*` (snake_case) + `imgui_default_actions()`.
- Поля класса: `keymap_config m_keymap`, `bool m_keybind_open`,
`std::string m_keybind_recording, m_keybind_status`. Инициализация в конструкторе.
- `handle_events()`: блок «global keys» переписан на `shortcut_pressed(m_keymap.shortcut(ID))`;
в начале `if(!m_keybind_recording.empty()) return;`.
- `init_debugger`: `config_register("debugger", …)`; **РАСШИРЕН `m_mapping`** — добавлены
F1/F2/F4, все буквы, 0-9, Space, Insert (иначе MAME не прокидывает эти клавиши в ImGui и
их нельзя ни нажать, ни записать).
- Меню Debug: ярлыки из `m_keymap.shortcut(ID).to_string()`, пункт «Customize keys...».
- Новые методы: `config_load`, `config_save`, `draw_keybindings()` (окно с таблицей,
запись клавиш, Esc/Delete, конфликты, Reset All). Вызов `draw_keybindings()` в `update()`.
### Qt — 3 файла (без новых файлов и без новых moc-классов; диалог инлайн на лямбдах)
- `qt/windowqt.h`: include `"../debugkeyconfig.h"`; в `DebuggerQt`
`virtual keymap_config &keymap()=0`, сигнал `keyBindingsChanged()`, `notifyKeyBindingsChanged()`;
в `WindowQt` — слоты `applyKeyBindings()`, `debugActCustomizeKeys()`, метод
`createKeyAction(id,text,slot)`, поле `std::map<std::string,QAction*> m_keyActions`.
Объявлена `std::vector<key_action> qtDefaultKeyActions();`.
- `qt/windowqt.cpp`: id-константы `ACT_*` + `qtDefaultKeyActions()`; действия создаются через
`createKeyAction` (ярлык из keymap, сохраняется в map); пункт «Customize Keys...»;
`applyKeyBindings()`; `debugActCustomizeKeys()` — инлайн `QDialog` с `QKeySequenceEdit`
на каждое действие, кнопки Ok/Cancel/RestoreDefaults; по OK пишет в keymap (через
`QKeySequence::toString(PortableText)`, берёт первый аккорд) и `notifyKeyBindingsChanged()`.
- `debugqt.cpp`: член `keymap_config m_keymap{qtDefaultKeyActions()}`, override `keymap()`,
в `configuration_load/save` добавлена ветка `config_type::DEFAULT``m_keymap.load/save`.
- **Дефолты Qt ИЗМЕНЕНЫ** со странных `F16F19` (заглушка в оригинале) на нормальные
F5/F6/F7/F8/F11/F10/Shift+F11/F3/Shift+F3/Ctrl+M,D,L,B/Ctrl+W/Ctrl+Q — единые с остальными.
### Build-скрипты
- `scripts/src/osd/modules.lua` — добавлены `debugkeyconfig.cpp/.h` в общий
`osdmodulesbuild()` (компилируется во ВСЕХ OSD).
- `scripts/src/osd/mac.lua`, `sdl.lua`, `sdl3.lua` — добавлены 4 osx-файла Cocoa
(`debugkeymap.{h,mm}`, `debugkeymapviewer.{h,mm}`).
- ImGui/Qt новых файлов не добавляли — правки в существующих.
---
## Сборка и проверка (то, что использовалось)
Окружение: macOS, OSD `sdl3`, конфиг `release64`, тулчейн `gmake-osx-clang`, Qt5 (`/usr/local/bin/qmake`).
Регенерация проекта (ОБЯЗАТЕЛЬНО с `--USE_QTDEBUG=1`, иначе qt-файлы выпадают из сборки):
```
cd /Users/tolik/Documents/GitHub/mame
3rdparty/genie/bin/darwin/genie --with-emulator --USE_QTDEBUG=1 --OPTIMIZE=3 \
--target='mame' --subtarget='mame' --build-dir='build' --osd='sdl3' \
--targetos='macosx' --PLATFORM='x86' --gcc=osx-clang --gcc_version=17.0.0 gmake
```
Сборка только нужных библиотек (быстро, без линковки всего MAME):
```
make -R --no-print-directory -C build/projects/sdl3/mame/gmake-osx-clang config=release64 osd_sdl3 qtdbg_sdl3
```
- `osd_sdl3` содержит `debugimgui.o`, `debugkeyconfig.o`, и osx-файлы Cocoa.
- `qtdbg_sdl3` содержит `debugqt.o`, `windowqt.o` + moc.
Статус последней сборки: **всё компилируется чисто, без ошибок/предупреждений** (по теме).
Полный бинарник (`mame`) НЕ релинковали — релинк потянул бы пересборку всего MAME.
Для живого теста нужен полный билд (напр. `make macosx_arm64_clang` или скрипт пользователя),
затем `~/Documents/MAME/debug.sh` (там `-debugger auto` → Cocoa). Для ImGui/Qt — сменить
`-debugger` (imgui требует `-video bgfx`).
Гочи сборки:
- genie без `--USE_QTDEBUG=1` отключает qt → `windowqt.o` пропадает из всех `.make`
(был эпизод: казалось, что файл не пересобирается).
- Объекты лежат в `build/osx_clang/obj/x64/Release/<lib>/...`.
- `qmake -query QT_INSTALL_LIBS` даёт `-F` для фреймворков (macOS).
---
## Что осталось / возможные продолжения
1. **Win-дебаггер** (пропущен). Если делать: ключи в `win/debugwininfo.cpp`
(`handle_key`, `WM_KEYDOWN`-switch по `VK_*` + `GetAsyncKeyState`) и
`win/disasmbasewininfo.cpp`; текст меню в `create_standard_menubar()`
(строки вида `"Run\tF5"`); персист через `debugwin` config (`DEFAULT`); пункт
«Customize keys…» + Win32-диалог (самое рискованное вслепую). Можно переиспользовать
`debugkeyconfig`; нужен маппинг `key_shortcut`↔`VK_*`. Текстовый формат уже совместим —
Windows-юзер и так может настроить через `default.cfg`/Qt/ImGui, а Win подхватит.
2. **Полный релинк** и интерактивная проверка ImGui/Qt вживую (запись клавиш, сохранение в
`default.cfg`, перезапуск — раскладка восстановилась).
3. Возможная унификация Cocoa на тот же текстовый формат `debugkeyconfig` (сейчас отдельный) —
не обязательно.
## Действия (id → дефолт), для ориентира
ImGui (snake_case): new_disasm=Ctrl+D, new_memory=Ctrl+M, new_bpoints=Ctrl+B,
new_wpoints=Ctrl+W, new_log=Ctrl+L, run=F5, run_next_cpu=F6, run_next_int=F7,
run_vblank=F8, run_and_hide=F12, step_into=F11, step_over=F10, step_out=F9,
soft_reset=F3, hard_reset=Shift+F3.
Qt (snake_case): new_memory=Ctrl+M, new_disasm=Ctrl+D, new_log=Ctrl+L, new_points=Ctrl+B,
new_devices=(нет), run=F5, run_and_hide=F12, run_next_cpu=F6, run_next_int=F7,
run_vblank=F8, step_into=F11, step_over=F10, step_out=Shift+F11, soft_reset=F3,
hard_reset=Shift+F3, close_window=Ctrl+W, quit=Ctrl+Q.