From 6cc8611d03407f800535fdd3d4bfee35515a198f Mon Sep 17 00:00:00 2001 From: Alexander Petrov Date: Thu, 27 Aug 2026 15:50:59 +0300 Subject: [PATCH] =?UTF-8?q?SprPoP:=20README=20=D0=B4=D0=BB=D1=8F=20=D0=B8?= =?UTF-8?q?=D0=B3=D1=80=D0=BE=D0=BA=D0=B0=20=D0=B8=20=D1=8D=D0=BA=D1=80?= =?UTF-8?q?=D0=B0=D0=BD=20Controls=20=D0=B2=20=D0=B4=D0=B2=D0=B5=20=D0=BA?= =?UTF-8?q?=D0=BE=D0=BB=D0=BE=D0=BD=D0=BA=D0=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit README, который едет НА ДИСК рядом с программой, в двух версиях: README.TXT (английский) и README.RUS (русский). Краткое описание, запуск, полная раскладка управления, читы, файлы игры, чего не хватает против оригинала, благодарности. Русский обязан быть в CP866 — DSS и местные просмотрщики читают именно её, UTF-8 показался бы кракозябрами. Исходники лежат в dist/ как UTF-8 (чтобы читались в репозитории), перекодировка и CRLF делаются правилом Makefile. ПОРЯДОК В КОНВЕЙЕРЕ ВАЖЕН: sed ставит CRLF ДО iconv — BSD sed в UTF-8 локали отказывается работать с байтами CP866 («RE error: illegal byte sequence»), а с валидным UTF-8 работает. iconv БЕЗ -c намеренно: потеря символа должна ломать сборку, а не молча портить текст. ЭКРАН CONTROLS переписан в две колонки. В одну раскладка больше не помещалась: после фаз A-C клавиш стало вдвое больше, а по высоте есть только 200 точек вместе с заголовком. Слева игра (бег, лазание, бой), справа служебное и читы; высота блока считается по ДЛИННОЙ колонке. Строка «IN A FIGHT» — заголовок, а не клавиша: ниже неё те же стрелки и Shift означают другое, и без разделителя список читался бы противоречиво. Заодно экран перестал врать: там до сих пор висели P, I, U и F7/F8 — клавиши, переназначенные ещё в фазе A. Проверено в MAME: Backspace открывает меню, Settings -> Show key bindings показывает обе колонки целиком. Co-Authored-By: Claude Opus 5 --- applications/SprPoP/Makefile | 29 +++- applications/SprPoP/assets/packed/README.RUS | 130 ++++++++++++++++++ applications/SprPoP/assets/packed/README.TXT | 134 +++++++++++++++++++ applications/SprPoP/dist/README.ru.txt | 130 ++++++++++++++++++ applications/SprPoP/dist/README.txt | 134 +++++++++++++++++++ applications/SprPoP/src/pop_menu.c | 95 +++++++++---- 6 files changed, 620 insertions(+), 32 deletions(-) create mode 100644 applications/SprPoP/assets/packed/README.RUS create mode 100644 applications/SprPoP/assets/packed/README.TXT create mode 100644 applications/SprPoP/dist/README.ru.txt create mode 100644 applications/SprPoP/dist/README.txt diff --git a/applications/SprPoP/Makefile b/applications/SprPoP/Makefile index fe4951c..b02c078 100644 --- a/applications/SprPoP/Makefile +++ b/applications/SprPoP/Makefile @@ -200,7 +200,11 @@ LVL_NUMS := 00 01 02 03 04 05 06 07 08 09 10 11 12 13 14 # три секунды. Четыре архива актёров, а не один: имена внутри наборов # совпадают (g0.atl есть и у стража, и у скелета, и у Джафара), а константы # индексов упаковщик делает из имени файла. -DISK := BG/bg.arc BG/pop_tile.pal BG/pal_tile.pal \ +# README для игрока идёт НА ДИСК рядом с программой. Русский обязан быть в +# CP866: DSS и любой местный просмотрщик читают именно её, UTF-8 покажется +# кракозябрами. Имена в 8.3: README.TXT и README.RUS. +DISK := README.TXT README.RUS \ + BG/bg.arc BG/pop_tile.pal BG/pal_tile.pal \ KID/kid.arc KID/kid.pal KID/kid.ani \ GUARD/guard.arc SKEL/skel.arc VIZIER/vizier.arc SHADOW/shadow.arc \ SND/snd.arc \ @@ -409,6 +413,23 @@ $(PACKED)/LEVELS/res20$(1).bin: $(LVL_ORIG)/res20$(1).bin | check-orig endef $(foreach n,$(LVL_NUMS),$(eval $(call lvl_rule,$(n)))) +# README: перевод строки CRLF (текст читают в DOS-подобной среде) и, для +# русского, перекодировка в CP866. iconv БЕЗ -c намеренно: потеря символа +# должна ломать сборку, а не молча портить текст (memory +# iconv_cp866_workflow; //TRANSLIT на macOS падает). +$(PACKED)/README.TXT: dist/README.txt + @mkdir -p $(dir $@) + @sed 's/$$/\r/' $< > $@ + +# ПОРЯДОК ВАЖЕН: CRLF ставится ДО перекодировки. BSD sed в UTF-8 локали +# отказывается работать с байтами CP866 («RE error: illegal byte sequence»), +# а с валидным UTF-8 — работает. +$(PACKED)/README.RUS: dist/README.ru.txt + @mkdir -p $(dir $@) + @sed 's/$$/\r/' $< | iconv -f UTF-8 -t CP866 > $@ + +resources-readme: $(PACKED)/README.TXT $(PACKED)/README.RUS + resources-bg: $(PACKED)/BG/bg.arc $(PACKED)/BG/pop_tile.pal $(PACKED)/BG/pal_tile.pal resources-kid: $(PACKED)/KID/kid.arc $(PACKED)/KID/kid.pal $(PACKED)/KID/kid.ani resources-actors: $(PACKED)/GUARD/guard.arc $(PACKED)/SKEL/skel.arc \ @@ -439,9 +460,9 @@ $(PACKED_FILES) $(GEN_H): @echo "SprPoP: нет $@ — генерирую ресурсы" @$(MAKE) GENERATE=1 $@ -RES_TARGETS := resources resources-bg resources-kid resources-actors \ - resources-sound resources-music resources-font resources-title \ - resources-pv resources-levels +RES_TARGETS := resources resources-readme resources-bg resources-kid \ + resources-actors resources-sound resources-music resources-font \ + resources-title resources-pv resources-levels $(RES_TARGETS): @$(MAKE) GENERATE=1 $@ # Перегенерация ВСЕГО, не глядя на таймстемпы. diff --git a/applications/SprPoP/assets/packed/README.RUS b/applications/SprPoP/assets/packed/README.RUS new file mode 100644 index 0000000..af46062 --- /dev/null +++ b/applications/SprPoP/assets/packed/README.RUS @@ -0,0 +1,130 @@ +=========================================================================== + SprPoP -- Prince of Persia Sprinter Sp2000 +=========================================================================== + + Prince of Persia ठ 孥 (1989) Sprinter Sp2000. + +䨪 VGA-ᨨ MS-DOS, ० 320x256 ன 256 +梥⮢; 몠 㪮 䥪 - ਣ ஢, १ + CBL. ୠ ஢, ⠢, ࠭ ਨ, +㯫 ਭᮩ ஬, 䨭 ⠡ ४म. + + + +--------------------------------------------------------------------------- + ப DSS, ⮬ ᪥, : + + sprpop + +冷 ணࠬ ⠫ 묨: + + BG\ ⠩ 䮭 KID\ ਭ + GUARD\ ࠦ SKEL\ ᪥ + VIZIER\ SHADOW\ ⥭ + SND\ 㪮 䥪 MUS\ 몠 + FONT\ TITLE\ ⠢ + PV\ 㯫 LEVELS\ ୠ ஢ + + - ⠫ ࠢ , , +, . + + + +--------------------------------------------------------------------------- + + + / ࠢ + 릮 + + + /ࠢ 릮 + Shift । + Shift + /ࠢ ஦ 蠣 + Home + 릮 + PgUp +ࠢ 릮 ࠢ + 릮 ࠧ + Shift 楯 ୨ + + + + / ࠢ 㯠 㯠 + Shift 㤠 + + + (Shift ᭮) + + 室 + + Backspace Esc 㧠 + ஡ ᪮쪮 ⠫ ६ + T ঠ ⠩ ࠭ + F6 ஥ ࠭ + F9 㧪 + Ctrl+A ஢ + Ctrl+R ⠢ + Ctrl+S / 몫 + Ctrl+M 몠 / 몫 + Ctrl+V ᡮન + Ctrl+Q F10 室 + +F10 ࠡ⠥ , ⮬ ᫥ ६ ⠢.  㣠 +⠢ ࠭ ਨ ய᪠ 稭 . + + + +--------------------------------------------------------------------------- + ਣ; ⮩ ᡮથ 祭 㬮砭. 몫 +࠭ ஥. + + Shift+L ᫥騩 ஢ + + / - / + K 㡨 ࠦ + Shift+I ॢ ࠭ + Shift+W + Shift+S ஢ + Shift+T ਡ ஢ ( ) + [ / ] ਭ ᥫ + + ⮢ ਣ : R ( ਭ) H / J / U / N + Ctrl+B (ᬮ ᥤ ). + +⫠ ⮣ , ਣ . +Ctrl, ⮡ 㪢 ᪫ . + + Ctrl+I ᬥ⨥: 몫 / / + Ctrl+P ० ᪮ + Ctrl+F ⠭ ᭮ + Ctrl+D ⫠筠 ப: ஢, , ᪮, + Ctrl++ / Ctrl+- ३ ᫥ / । + + +, +--------------------------------------------------------------------------- + POP.CFG ன + POP.SAV ஥ ࠭, POP.BAK - ।饥 + POP.HOF ⠡ ४म + +  冷 ணࠬ,  㤠 - + 祭 㬮砭. + + + +--------------------------------------------------------------------------- + ୠ ஢ ன. த ࠧ, ⠪ +客 ; , , ᯨ᪥ + ஥. + +⨢ ਣ 墠⠥: R ( ਭ), ⮢ H / J / U / N + Ctrl+B ᬮ ᥤ ᭨ ࠭ (F12). + + + +--------------------------------------------------------------------------- +Prince of Persia ਤ㬠 ᠫ ठ 孥 1989 . + +堭 ⮣ ᢥ﫠 SDLPoP (github.com/NagyD/SDLPoP) - +ᠬ 筮 ⥭ ⮣, ᥡ ਣ . 䨪 + ᨨ MS-DOS, 㪮 䥪 - 䠩 DIGISND, 몠 +- ᥩ 㭤४ DOS-ᨨ. + + ᮡ࠭ 訬 ஬ sprinter-cc ᭮ SDCC Sprinter +Sp2000. diff --git a/applications/SprPoP/assets/packed/README.TXT b/applications/SprPoP/assets/packed/README.TXT new file mode 100644 index 0000000..a867d67 --- /dev/null +++ b/applications/SprPoP/assets/packed/README.TXT @@ -0,0 +1,134 @@ +=========================================================================== + SprPoP -- Prince of Persia for the Sprinter Sp2000 +=========================================================================== + +A port of Jordan Mechner's Prince of Persia (1989) to the Sprinter Sp2000. + +The graphics are the VGA ones from the MS-DOS release, in 320x256 with a +256-colour palette; the music and the sound effects are the digitised +originals, played through the CBL channel. All fourteen levels, the title +sequence, the story screens, the intro with the Princess and Jaffar, the +ending and the hall of fame are in. + + +RUNNING IT +--------------------------------------------------------------------------- +From the DSS prompt, on the drive the game sits on: + + sprpop + +The game needs its data directories next to the program: + + BG\ background tiles KID\ the prince + GUARD\ guards SKEL\ the skeleton + VIZIER\ Jaffar SHADOW\ the shadow + SND\ sound effects MUS\ music + FONT\ text font TITLE\ title screens + PV\ story and intro screens LEVELS\ the fourteen levels + +If a directory is missing the game still starts, but whatever lived there +will be silent or invisible. + + +CONTROLS +--------------------------------------------------------------------------- +Running and climbing + + Left / Right turn, or run + Up jump, or climb up + Down crouch, or climb down + Down + Left/Right hop + Shift pick things up + Shift + Left/Right careful step + Home or Up+Left jump to the left + PgUp or Up+Right jump to the right + Up while running running jump + Shift while falling grab onto a ledge + +Sword fighting + + Left / Right advance or retreat + Shift strike + Up block + Down put the sword away + (Shift draws it again) + +While the game runs + + Backspace or Esc pause and open the menu + Space how much time is left + T keep the timer on screen + F6 quicksave + F9 quickload + Ctrl+A restart the level + Ctrl+R back to the title screen + Ctrl+S sound on / off + Ctrl+M music on / off + Ctrl+V show the build version + Ctrl+Q or F10 quit + +F10 works everywhere, including the title sequence. Any other key during +the titles or the story screens skips straight into the game. + + +CHEATS +--------------------------------------------------------------------------- +The cheats of the original, and they are on by default in this build. You +can turn them off on the Settings screen. + + Shift+L go to the next level + + / - one minute more / less + K kill the guard + Shift+I turn the screen upside down + Shift+W slow falling + Shift+S restore one hit point + Shift+T one more hit point (up to ten) + [ / ] nudge the prince one pixel + +Two cheats of the original are NOT here yet: R (resurrect the prince) and +H / J / U / N with Ctrl+B (look at the neighbouring room). + +Debug keys of this port, which the original has no equivalent for. They +all sit under Ctrl so that no plain letter is taken away from the layout +above. + + Ctrl+I immortality: off / in combat / almost everything + Ctrl+P speed mode + Ctrl+F freeze the frame, and unfreeze it + Ctrl+D debug bar: level, room, speed, sound, timer + Ctrl++ / Ctrl+- jump to the next / previous room by number + + +FILES THE GAME WRITES +--------------------------------------------------------------------------- + POP.CFG settings + POP.SAV quicksave, and POP.BAK the one before it + POP.HOF hall of fame + +All of them appear next to the program, and all of them can be deleted -- +the game will simply start from its defaults again. + + +WHAT IS NOT FINISHED +--------------------------------------------------------------------------- +All fourteen levels have been played through. The port is still under +active development, so rough edges do turn up; the ones we know about are +tracked in the project's own bug list. + +Missing against the original: the R cheat (resurrect the prince), the +H / J / U / N and Ctrl+B cheats for looking at neighbouring rooms, and the +screenshot key (F12). + + +CREDITS +--------------------------------------------------------------------------- +Prince of Persia was created by Jordan Mechner in 1989. + +The mechanics of this port were checked against SDLPoP +(github.com/NagyD/SDLPoP), which is the authoritative reading of how the +original engine behaves. The graphics come from the MS-DOS release, the +sound effects from its DIGISND files, and the music from recordings of the +DOS soundtrack. + +The port itself is built with sprinter-cc, our SDCC-based toolchain for the +Sprinter Sp2000. diff --git a/applications/SprPoP/dist/README.ru.txt b/applications/SprPoP/dist/README.ru.txt new file mode 100644 index 0000000..e9ca085 --- /dev/null +++ b/applications/SprPoP/dist/README.ru.txt @@ -0,0 +1,130 @@ +=========================================================================== + SprPoP -- Prince of Persia для Sprinter Sp2000 +=========================================================================== + +Порт игры Prince of Persia Джордана Мехнера (1989) на Sprinter Sp2000. + +Графика взята из VGA-версии для MS-DOS, режим 320x256 с палитрой на 256 +цветов; музыка и звуковые эффекты - оригинальные оцифровки, играются через +канал CBL. В игре все четырнадцать уровней, заставка, экраны истории, +вступление с принцессой и Джафаром, финал и таблица рекордов. + + +ЗАПУСК +--------------------------------------------------------------------------- +Из командной строки DSS, на том диске, где лежит игра: + + sprpop + +Рядом с программой должны лежать её каталоги с данными: + + BG\ тайлы фона KID\ принц + GUARD\ стражи SKEL\ скелет + VIZIER\ Джафар SHADOW\ тень + SND\ звуковые эффекты MUS\ музыка + FONT\ шрифт TITLE\ заставка + PV\ история и вступление LEVELS\ четырнадцать уровней + +Без какого-нибудь каталога игра всё равно запустится, но то, что в нём +лежало, окажется беззвучным или невидимым. + + +УПРАВЛЕНИЕ +--------------------------------------------------------------------------- +Бег и лазание + + Влево / Вправо повернуться или бежать + Вверх прыжок или подтянуться + Вниз присесть или спуститься + Вниз + Влево/Вправо прыжок на месте + Shift подобрать предмет + Shift + Влево/Вправо осторожный шаг + Home или Вверх+Влево прыжок влево + PgUp или Вверх+Вправо прыжок вправо + Вверх на бегу прыжок с разбега + Shift в падении зацепиться за карниз + +Бой на мечах + + Влево / Вправо наступать или отступать + Shift удар + Вверх защита + Вниз убрать меч + (Shift достаёт его снова) + +По ходу игры + + Backspace или Esc пауза и меню + Пробел сколько осталось времени + T держать таймер на экране + F6 быстрое сохранение + F9 быстрая загрузка + Ctrl+A начать уровень заново + Ctrl+R вернуться к заставке + Ctrl+S звук вкл / выкл + Ctrl+M музыка вкл / выкл + Ctrl+V показать версию сборки + Ctrl+Q или F10 выход + +F10 работает везде, в том числе во время заставки. Любая другая клавиша на +заставке или на экранах истории пропускает их и начинает игру. + + +ЧИТЫ +--------------------------------------------------------------------------- +Читы оригинала; в этой сборке они включены по умолчанию. Выключить можно на +экране настроек. + + Shift+L следующий уровень + + / - на минуту больше / меньше + K убить стража + Shift+I перевернуть экран + Shift+W медленное падение + Shift+S вернуть одну единицу здоровья + Shift+T прибавить здоровья (до десяти) + [ / ] подвинуть принца на пиксель + +Двух читов оригинала пока нет: R (воскресить принца) и H / J / U / N вместе +с Ctrl+B (посмотреть соседнюю комнату). + +Отладочные клавиши этого порта, которых в оригинале нет вовсе. Все они под +Ctrl, чтобы не занимать простые буквы из раскладки выше. + + Ctrl+I бессмертие: выкл / в бою / почти во всём + Ctrl+P режим скорости + Ctrl+F остановить кадр и снова пустить + Ctrl+D отладочная строка: уровень, комната, скорость, звук + Ctrl++ / Ctrl+- перейти в следующую / предыдущую комнату по номеру + + +ФАЙЛЫ, КОТОРЫЕ СОЗДАЁТ ИГРА +--------------------------------------------------------------------------- + POP.CFG настройки + POP.SAV быстрое сохранение, POP.BAK - предыдущее + POP.HOF таблица рекордов + +Все они появляются рядом с программой, и любой можно удалить - игра просто +начнёт со значений по умолчанию. + + +ЧТО ЕЩЁ НЕ ГОТОВО +--------------------------------------------------------------------------- +Все четырнадцать уровней пройдены. Порт продолжает развиваться, так что +шероховатости ещё встречаются; те, о которых мы знаем, ведутся в списке +багов проекта. + +Против оригинала не хватает: чита R (воскресить принца), читов H / J / U / N +и Ctrl+B для осмотра соседних комнат и клавиши снимка экрана (F12). + + +БЛАГОДАРНОСТИ +--------------------------------------------------------------------------- +Prince of Persia придумал и написал Джордан Мехнер в 1989 году. + +Механика этого порта сверялась с SDLPoP (github.com/NagyD/SDLPoP) - это +самое точное прочтение того, как ведёт себя оригинальный движок. Графика +взята из версии для MS-DOS, звуковые эффекты - из её файлов DIGISND, музыка +- из записей саундтрека DOS-версии. + +Сам порт собран нашим компилятором sprinter-cc на основе SDCC для Sprinter +Sp2000. diff --git a/applications/SprPoP/dist/README.txt b/applications/SprPoP/dist/README.txt new file mode 100644 index 0000000..0599c43 --- /dev/null +++ b/applications/SprPoP/dist/README.txt @@ -0,0 +1,134 @@ +=========================================================================== + SprPoP -- Prince of Persia for the Sprinter Sp2000 +=========================================================================== + +A port of Jordan Mechner's Prince of Persia (1989) to the Sprinter Sp2000. + +The graphics are the VGA ones from the MS-DOS release, in 320x256 with a +256-colour palette; the music and the sound effects are the digitised +originals, played through the CBL channel. All fourteen levels, the title +sequence, the story screens, the intro with the Princess and Jaffar, the +ending and the hall of fame are in. + + +RUNNING IT +--------------------------------------------------------------------------- +From the DSS prompt, on the drive the game sits on: + + sprpop + +The game needs its data directories next to the program: + + BG\ background tiles KID\ the prince + GUARD\ guards SKEL\ the skeleton + VIZIER\ Jaffar SHADOW\ the shadow + SND\ sound effects MUS\ music + FONT\ text font TITLE\ title screens + PV\ story and intro screens LEVELS\ the fourteen levels + +If a directory is missing the game still starts, but whatever lived there +will be silent or invisible. + + +CONTROLS +--------------------------------------------------------------------------- +Running and climbing + + Left / Right turn, or run + Up jump, or climb up + Down crouch, or climb down + Down + Left/Right hop + Shift pick things up + Shift + Left/Right careful step + Home or Up+Left jump to the left + PgUp or Up+Right jump to the right + Up while running running jump + Shift while falling grab onto a ledge + +Sword fighting + + Left / Right advance or retreat + Shift strike + Up block + Down put the sword away + (Shift draws it again) + +While the game runs + + Backspace or Esc pause and open the menu + Space how much time is left + T keep the timer on screen + F6 quicksave + F9 quickload + Ctrl+A restart the level + Ctrl+R back to the title screen + Ctrl+S sound on / off + Ctrl+M music on / off + Ctrl+V show the build version + Ctrl+Q or F10 quit + +F10 works everywhere, including the title sequence. Any other key during +the titles or the story screens skips straight into the game. + + +CHEATS +--------------------------------------------------------------------------- +The cheats of the original, and they are on by default in this build. You +can turn them off on the Settings screen. + + Shift+L go to the next level + + / - one minute more / less + K kill the guard + Shift+I turn the screen upside down + Shift+W slow falling + Shift+S restore one hit point + Shift+T one more hit point (up to ten) + [ / ] nudge the prince one pixel + +Two cheats of the original are NOT here yet: R (resurrect the prince) and +H / J / U / N with Ctrl+B (look at the neighbouring room). + +Debug keys of this port, which the original has no equivalent for. They +all sit under Ctrl so that no plain letter is taken away from the layout +above. + + Ctrl+I immortality: off / in combat / almost everything + Ctrl+P speed mode + Ctrl+F freeze the frame, and unfreeze it + Ctrl+D debug bar: level, room, speed, sound, timer + Ctrl++ / Ctrl+- jump to the next / previous room by number + + +FILES THE GAME WRITES +--------------------------------------------------------------------------- + POP.CFG settings + POP.SAV quicksave, and POP.BAK the one before it + POP.HOF hall of fame + +All of them appear next to the program, and all of them can be deleted -- +the game will simply start from its defaults again. + + +WHAT IS NOT FINISHED +--------------------------------------------------------------------------- +All fourteen levels have been played through. The port is still under +active development, so rough edges do turn up; the ones we know about are +tracked in the project's own bug list. + +Missing against the original: the R cheat (resurrect the prince), the +H / J / U / N and Ctrl+B cheats for looking at neighbouring rooms, and the +screenshot key (F12). + + +CREDITS +--------------------------------------------------------------------------- +Prince of Persia was created by Jordan Mechner in 1989. + +The mechanics of this port were checked against SDLPoP +(github.com/NagyD/SDLPoP), which is the authoritative reading of how the +original engine behaves. The graphics come from the MS-DOS release, the +sound effects from its DIGISND files, and the music from recordings of the +DOS soundtrack. + +The port itself is built with sprinter-cc, our SDCC-based toolchain for the +Sprinter Sp2000. diff --git a/applications/SprPoP/src/pop_menu.c b/applications/SprPoP/src/pop_menu.c index 5305218..ed0d9fe 100644 --- a/applications/SprPoP/src/pop_menu.c +++ b/applications/SprPoP/src/pop_menu.c @@ -90,13 +90,22 @@ #define SET_HEAD2 (SET_HEAD1 + 4 * SET_STEP + SET_HEAD_GAP) #define SET_HEAD3 (SET_HEAD2 + 3 * SET_STEP + SET_HEAD_GAP) -/* CONTROLS: число строк зависит от того, включены ли читы, поэтому верх - * блока считается в рантайме. */ -#define CTRL_TITLE_GAP 20 -#define CTRL_N_BASE 7 /* общие клавиши */ -#define CTRL_N_CHEAT 5 /* дополнительные строки читов */ -#define CTRL_COL_KEY 45 -#define CTRL_COL_DESC 145 +/* CONTROLS — ДВЕ КОЛОНКИ. В одну колонку раскладка уже не помещалась: + * после приведения клавиш к keys.txt (docs/keys_plan.md) их стало вдвое + * больше, а по высоте есть только 200 точек на всё вместе с заголовком. + * + * Слева — игра (бег, лазание, бой), справа — служебное и читы. Число строк + * в колонках разное и зависит от того, включены ли читы, поэтому высота + * блока считается в рантайме по ДЛИННОЙ колонке. */ +#define CTRL_TITLE_GAP 18 +#define CTRL_N_LEFT 10 /* игровые клавиши */ +#define CTRL_N_SYS 7 /* служебные */ +#define CTRL_N_CHEAT 5 /* читы: показываются, только если включены */ +#define CTRL_L_KEY 6 +#define CTRL_L_DESC 62 +#define CTRL_R_KEY 164 +#define CTRL_R_DESC 220 +#define CTRL_STEP 13 /* ABOUT = ровно тот же текст, что на стартовом Sprinter screen, минус * строка про клавиши. ABOUT_H — и высота блока, и смещение ПОСЛЕДНЕЙ @@ -317,39 +326,69 @@ static void settings_draw(uint8_t sel) /* Две колонки «клавиша — что делает». Первые CTRL_N_BASE строк общие, за * ними идут читовые: их показываем, только когда читы включены. */ -static const char * const ctrl_key[CTRL_N_BASE + CTRL_N_CHEAT] = { - "ARROWS", "SHIFT", "ESC", "F6 / F9", "CTRL+S", "CTRL+M", "P", - "K", "I", "SHIFT+L", "U", "F7 / F8" +/* ЛЕВАЯ КОЛОНКА — игра. Строка «IN A FIGHT» здесь заголовок, а не клавиша: + * ниже неё те же стрелки и Shift означают уже другое, и без разделителя + * список читался бы как противоречивый. */ +static const char * const ctrl_l_key[CTRL_N_LEFT] = { + "ARROWS", "UP", "DOWN", "SHIFT", "SH+ARROWS", "HOME PGUP", + "IN A FIGHT", "SHIFT", "UP", "DOWN" +}; +static const char * const ctrl_l_desc[CTRL_N_LEFT] = { + "RUN / TURN", "JUMP, CLIMB", "CROUCH", "PICK UP", "CAREFUL STEP", + "JUMP L / R", + "", "STRIKE", "BLOCK", "SHEATHE" }; -static const char * const ctrl_desc[CTRL_N_BASE + CTRL_N_CHEAT] = { - "MOVE / JUMP", "ACTION", "PAUSE MENU", "SAVE / LOAD", "SOUND", "MUSIC", - "SPEED", - "KILL GUARD", "IMMORTAL", "NEXT LEVEL", "FLIP SCREEN", "TIME - / +" +/* ПРАВАЯ КОЛОНКА — служебное, ниже читы. */ +static const char * const ctrl_r_key[CTRL_N_SYS + 1 + CTRL_N_CHEAT] = { + "BACKSPACE", "SPACE", "T", "F6 / F9", "CTRL+A", "CTRL+S M", "CTRL+Q F10", + "CHEATS", + "SHIFT+L", "K", "+ / -", "SHIFT+I", "SHIFT+S T" }; +static const char * const ctrl_r_desc[CTRL_N_SYS + 1 + CTRL_N_CHEAT] = { + "MENU", "TIME LEFT", "SHOW TIMER", "SAVE / LOAD", "RESTART LVL", + "SOUND / MUSIC", "QUIT", + "", + "NEXT LEVEL", "KILL GUARD", "TIME + / -", "FLIP SCREEN", "HEAL / MAX HP" +}; + +/* Одна строка колонки: слева клавиша, справа что она делает. Пустое + * описание — значит строка была заголовком секции, и клавишу мы печатаем + * как есть, без второго столбца. */ +static void ctrl_row(int kx, int dx, int y, const char *key, const char *desc) +{ + pop_text_draw_mapped(POP_TEXT_SMALL, kx, y, key); + if (desc[0]) pop_text_draw_mapped(POP_TEXT_SMALL, dx, y, desc); +} static void controls_draw(void) { uint8_t back = ui_begin(); - /* С выключенными читами вместо пяти строк идёт одна пояснительная — - * список короче, и блок обязан центрироваться по ФАКТИЧЕСКОЙ высоте. */ + /* С выключенными читами правая колонка короче: вместо пяти строк идёт + * одна пояснительная. Блок центрируется по ДЛИННОЙ из двух колонок. */ uint8_t cheats = pop_settings.cheats_enabled; - uint8_t rows = (uint8_t)(cheats ? CTRL_N_BASE + CTRL_N_CHEAT - : CTRL_N_BASE + 1); + uint8_t rright = (uint8_t)(cheats ? CTRL_N_SYS + 1 + CTRL_N_CHEAT + : CTRL_N_SYS + 1); + uint8_t rows = (uint8_t)(rright > CTRL_N_LEFT ? rright : CTRL_N_LEFT); uint8_t i; int top = UI_CENTER_TOP(POP_FONT_BIG_ASCENT + CTRL_TITLE_GAP + - (int)(rows - 1) * SET_STEP); - int y = top + POP_FONT_BIG_ASCENT; + (int)(rows - 1) * CTRL_STEP); + int y0 = top + POP_FONT_BIG_ASCENT; + int y; pop_text_map(); - pop_text_center_mapped(POP_TEXT_BIG, GFX_WIDTH / 2, y, "CONTROLS"); - y += CTRL_TITLE_GAP; - for (i = 0; i < rows; i++) { - const char *key = ctrl_key[i], *desc = ctrl_desc[i]; - if (!cheats && i == CTRL_N_BASE) { key = "CHEATS"; desc = "DISABLED"; } - pop_text_draw_mapped(POP_TEXT_SMALL, CTRL_COL_KEY, y, key); - pop_text_draw_mapped(POP_TEXT_SMALL, CTRL_COL_DESC, y, desc); - y += SET_STEP; + pop_text_center_mapped(POP_TEXT_BIG, GFX_WIDTH / 2, y0, "CONTROLS"); + y = y0 + CTRL_TITLE_GAP; + for (i = 0; i < CTRL_N_LEFT; i++, y += CTRL_STEP) + ctrl_row(CTRL_L_KEY, CTRL_L_DESC, y, ctrl_l_key[i], ctrl_l_desc[i]); + y = y0 + CTRL_TITLE_GAP; + for (i = 0; i < rright; i++, y += CTRL_STEP) { + const char *key = ctrl_r_key[i], *desc = ctrl_r_desc[i]; + + /* Заголовок секции читов: с выключенными читами он же и объясняет, + * почему список ниже пуст. */ + if (i == CTRL_N_SYS && !cheats) desc = "DISABLED"; + ctrl_row(CTRL_R_KEY, CTRL_R_DESC, y, key, desc); } pop_text_unmap(); ui_end(back);