Ctrl+S — вкл/выкл звук; чит «выдать меч» убран

Порт Ctrl+S из SDLPoP (seg000:657).  Выключение реально закрывает CBL, а
не глушит сэмпл: иначе насос продолжал бы отдавать блоки тишины и платить
те же 3,26 % процессорного времени.

Флаг намерения pop_snd_want отдельно от pop_snd_ok: последний гасит
служебная пауза на время загрузки уровня, и правь Ctrl+S только его —
первая же смена уровня вернула бы выключенный звук.

Индикация: пурпурная палочка в борте, когда звука НЕТ (включённый слышно
и так, а молчание неотличимо от «нечему звучать»).

Чит S «выдать меч» был отладочным и больше не нужен — снят, клавиша ушла
под звук.

Замер цены звука — sound_plan.md §9: 8 001 такт на прерывание при периоде
245 759 (3,26 % времени), +2,2 % к работе кадра в сцене 11/15, период
кадра не сдвинулся ни разу.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
2026-08-20 15:49:33 +03:00
parent 7e2e7fbb37
commit e0c86a96ef
7 changed files with 147 additions and 13 deletions
+25 -8
View File
@@ -318,7 +318,7 @@ uint8_t pop_dbg_roomnav(uint8_t dir) __banked
* Флаги «фронта» стали статиками модуля — раньше они были локалями main.
* Смысл прежний: одно нажатие = одно срабатывание.
*/
static uint8_t cheat_prev, immo_prev, sword_prev, nlvl_prev;
static uint8_t cheat_prev, immo_prev, sound_prev, nlvl_prev;
static uint8_t upsd_prev, xdec_prev, xinc_prev;
void pop_cheat_tick(void) __banked
@@ -328,8 +328,10 @@ void pop_cheat_tick(void) __banked
* K — убить стража;
* I — бессмертие Кида (наш отладочный, в оригинале его нет:
* иначе боёвку проверять получается ровно три раза);
* S — выдать меч, не бегая за ним в комнату 15. Штатно меч
* берётся с пола (pop_have_sword ставит подбор);
* Ctrl+S — вкл/выкл звук (порт Ctrl+S из SDLPoP, seg000:657).
* НЕ чит: работает и без pop_cheats, как в оригинале.
* Ctrl обязателен — голая S у нас свободна, но менять
* пользовательскую раскладку оригинала незачем;
* Shift+L — следующий уровень (seg000:698, ветка next_level =
* current_level + 1). Единственный вменяемый способ
* тестировать уровни 2..15. NB: L без Shift — отладочный
@@ -346,7 +348,8 @@ void pop_cheat_tick(void) __banked
* следующего кадра. */
uint8_t k = kbd_raw_down(KBD_CHEAT_KILL);
uint8_t i = kbd_raw_down(KBD_CHEAT_IMMO);
uint8_t s = kbd_raw_down(KBD_CHEAT_SWORD);
uint8_t s = (uint8_t)(kbd_raw_down(KBD_SOUND_TOGGLE) &&
(kbd_raw_down(KBD_LCTRL) || kbd_raw_down(KBD_RCTRL)));
uint8_t nl = (uint8_t)(kbd_raw_down(KBD_CHEAT_NEXTLVL) &&
(kbd_raw_down(KBD_LSHIFT) || kbd_raw_down(KBD_RSHIFT)));
uint8_t up = kbd_raw_down(KBD_CHEAT_UPSIDE);
@@ -357,7 +360,7 @@ void pop_cheat_tick(void) __banked
* мелкий урон» -> 0. Что означают уровни — pop_state.h. */
if (pop_cheats && i && !immo_prev)
pop_immortal = (uint8_t)(pop_immortal >= 2 ? 0 : pop_immortal + 1);
if (pop_cheats && s && !sword_prev) pop_have_sword = 1;
if (s && !sound_prev) pop_sfx_toggle(); /* не под pop_cheats */
if (pop_cheats && nl && !nlvl_prev && pop_current_level < POP_LAST_LEVEL)
pop_next_level = (uint8_t)(pop_current_level + 1);
/* U — переворот экрана (seg000:0793 — чит и в оригинале).
@@ -370,7 +373,7 @@ void pop_cheat_tick(void) __banked
if (pop_cheats && xi && !xinc_prev) Kid.x = (uint8_t)(Kid.x + 1);
cheat_prev = k;
immo_prev = i;
sword_prev = s;
sound_prev = s;
nlvl_prev = nl;
upsd_prev = up;
xdec_prev = xd;
@@ -388,6 +391,11 @@ void pop_cheat_tick(void) __banked
* белый x 100..175 комната (1..24)
* голубой x 190..205 скорость (1 палочка NORMAL, 2 FAST, 3 FASTEST)
* красный x 220..230 бессмертие (1 палочка = только бой, 2 = и мелкий урон)
* пурпурный x 245 звук ВЫКЛЮЧЕН (Ctrl+S) либо не поднялся вовсе
* Звук показан «от противного» — палочка есть, когда звука НЕТ. Иначе
* индикатор ничего не сообщает: включённый звук слышно и так, а вот
* молчание неотличимо от «в этот момент нечему звучать».
*
* ЦВЕТА — индексы ИГРОВОЙ палитры, и выбраны они не по вкусу, а по двум
* ограничениям.
@@ -413,6 +421,7 @@ static uint8_t room_label_sig = 0xFF; /* последняя показанна
static uint8_t lvl_label_sig = 0xFF; /* ...уровень */
static uint8_t spd_label_sig = 0xFF; /* ...режим скорости */
static uint8_t imm_label_sig = 0xFF; /* ...бессмертие */
static uint8_t snd_label_sig = 0xFF; /* ...звук (pop_snd_want) */
static uint8_t room_label_redraw; /* остаток кадров (2 = обе страницы) */
/* Группа палочек: n штук от x вправо, шаг 5, ширина 2. */
@@ -428,17 +437,21 @@ void pop_dbg_room_label(uint8_t room) __banked
* (`if (n != g) g = n;` пишет разность вместо значения). */
uint8_t prev_room = room_label_sig, prev_lvl = lvl_label_sig;
uint8_t prev_spd = spd_label_sig, prev_imm = imm_label_sig;
uint8_t prev_snd = snd_label_sig;
uint8_t lvl = pop_current_level, spd = pop_speed_mode, imm = pop_immortal;
uint8_t snd = pop_snd_want;
room_label_sig = room;
lvl_label_sig = lvl;
spd_label_sig = spd;
imm_label_sig = imm;
if (room != prev_room || lvl != prev_lvl || spd != prev_spd || imm != prev_imm)
snd_label_sig = snd;
if (room != prev_room || lvl != prev_lvl || spd != prev_spd ||
imm != prev_imm || snd != prev_snd)
room_label_redraw = 2;
if (!room_label_redraw) return;
setfillstyle(SOLID_FILL, BLACK);
bar(10, 0, 230, 5);
bar(10, 0, 250, 5);
setfillstyle(SOLID_FILL, 0x3E); /* уровень — жёлтый */
label_bars(10, (uint8_t)(lvl / 10));
@@ -457,6 +470,10 @@ void pop_dbg_room_label(uint8_t room) __banked
setfillstyle(SOLID_FILL, 0x3C);
label_bars(220, imm); /* палочек = уровень (1 или 2) */
}
if (!snd) { /* звука НЕТ — пурпурный */
setfillstyle(SOLID_FILL, 0x3D);
label_bars(245, 1);
}
room_label_redraw--;
}