MEM-BANK5: pop_ctrl.c → банк 5; чит [/] подгонки Кида по X
Три правки едут вместе намеренно: n_banks и --bank обязаны меняться атомарно, иначе промежуточный коммит — зависание (см. ниже). MEM-BANK5. CODE и DATA делят одно 32-КБ пространство W1+W2, поэтому килобайт кода, уехавший в банк, — это килобайт, доступный данным. Кандидат выбран не по размеру, а по частоте вызова: диспетчер управления дёргается раз в кадр на персонажа и горячих банк→банк переходов не создаёт (в отличие от pop_level, чей pop_level_tile зовётся из банка 2 на КАЖДЫЙ тайл). _CODE 26 780 -> 24 662 Б (−2 118) куча 180 -> 2 298 Б банк 5 2 211 / 16 384 (13.5 %) Шина control_* (8 глобалов) переехала в pop_state.c. Сегодня она уцелела бы и в pop_ctrl.c — банки собираются без --bank-data, их писучие данные остаются в общем _DATA, — но это флаг сборки, а не свойство кода, а шину трогают уже три банка: 5 пишет с клавиатуры, 1 подаёт синтетический ввод ИИ (autocontrol_*, seg002), 3 читает через pop_ctrl_shift_held. Заодно pop_ctrl.c наконец включает собственный заголовок — раньше объявления жили прямо в нём. ГРАБЛИ, на которые наступили (стоили дольше самой задачи): n_banks в roomtest.c захардкожен, и его надо править вместе с числом --bank. С n_banks=4 и пятым банком crt0 выделил четыре страницы, _bank_pages[5] остался нулём, и первый же вызов pop_ctrl_init() через трамплин отобразил в W3 страницу 0 и прыгнул на 0xC874 в мусор — исполнение забрело в дисковый код DSS и осталось крутить чтение секторов. Симптом: загрузка ресурсов проходит целиком (open=45 — все атласы), комната и Кид успевают нарисоваться из enter_room, а HP и номер комнаты уже нет, и kid_tick не вызывается ни разу. Ровно предупреждение из шапки runtime/bank.s. Сверку n_banks с реальным максимальным индексом банка записал в docs/TODO.md (Auto-banking) — это должно быть ошибкой сборки. DBG-CHEATS: [ (0x54) и ] (0x5B) двигают Кида на пиксель (seg000:1828), по фронту нажатия, под pop_cheats. Нужны потому, что мост MAME теряет нажатия при быстрой отправке и подогнать Кида в позу скриптом нельзя — на это упёрлись BUG-LOOSE-2 и BUG-GATE-PASS-1. ROOMNAV больше не зовёт pop_trob_reset: reset обнуляет room_seen, то есть чит ОТМАТЫВАЛ МИР (открытые/закрытые ворота, нажатые кнопки). Навигация обязана только телепортировать. Проверено в MAME: старт уровня 1 рисуется полностью (комната, Кид, HP, номер), бег вправо и падение на второй ряд отрабатывают, ] даёт x+1 и [ даёт x−1 по одному нажатию, Shift+→ — осторожный шаг (x 131 -> 142, колонка 4 -> 5) и при удержании 90 кадров не срывается в бег (x 142 -> 151), то есть pop_ctrl_shift_held работает через границу банк 3 -> банк 5. Наборы под ucsim: geom 39, grab 53, phys 1723 — все зелёные. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -17,6 +17,7 @@
|
||||
*/
|
||||
#include <stdint.h>
|
||||
#include <kbd_raw.h>
|
||||
#include "pop_ctrl.h" /* свой API (__banked) + объявления шины control_* */
|
||||
#include "pop_kid.h"
|
||||
#include "pop_map.h"
|
||||
#include "pop_guard.h" /* charid, состояние меча, seq стража */
|
||||
@@ -73,15 +74,15 @@
|
||||
#define FRAME_109_CROUCH 109
|
||||
|
||||
/* ---- Состояние управления (seg006 globals) ------------------------ *
|
||||
* control_x/y/shift — «сырое» состояние осей ЭТОГО кадра (абсолютно:
|
||||
* X LEFT/-1..RIGHT/+1); *_forward/backward/up/down/shift2 — конечный
|
||||
* автомат held/released/ignore (авто-повтор); ctrl1_* — их память между
|
||||
* кадрами (rest/save). */
|
||||
int8_t control_x, control_y, control_shift;
|
||||
/* НЕ static: в оригинале это глобалы, через которые ИИ стража подаёт
|
||||
* СИНТЕТИЧЕСКИЙ ввод (autocontrol_*, seg002), а дальше работает тот же
|
||||
* control(), что и у игрока. Поэтому шина общая. */
|
||||
int8_t control_forward, control_backward, control_up, control_down, control_shift2;
|
||||
* Сами control_* ЖИВУТ В pop_state.c, а не здесь. Модуль уехал в БАНК 5,
|
||||
* а шину пишут с трёх сторон (этот банк, guards.c из банка 1) и читают из
|
||||
* банка 3 (pop_map) — это ровно тот случай, для которого pop_state и
|
||||
* заведён. Сегодня оно работало бы и отсюда: банки собираются БЕЗ
|
||||
* --bank-data, поэтому их писучие данные остаются в общем _DATA. Но это
|
||||
* флаг сборки, а не свойство кода: включат --bank-data ради экономии
|
||||
* W1/W2 — и шина молча уедет в страницу банка.
|
||||
*
|
||||
* ctrl1_* остаются здесь: их трогает только этот модуль. */
|
||||
static int8_t ctrl1_forward, ctrl1_backward, ctrl1_up, ctrl1_down, ctrl1_shift2;
|
||||
|
||||
/* ---- seqtbl_offset_char: сменить последовательность Kid ------------ *
|
||||
@@ -549,7 +550,7 @@ static void control_with_sword(void)
|
||||
}
|
||||
|
||||
/* control() — диспетчер по кадру (seg005.c:252) для АКТИВНОГО персонажа. */
|
||||
void pop_control(void)
|
||||
void pop_control(void) __banked
|
||||
{
|
||||
uint8_t f = Char.frame;
|
||||
/* seg005 control(), самая первая ветка: персонаж УМИРАЕТ (alive >= 0).
|
||||
@@ -674,7 +675,7 @@ static void save_ctrl_1(void)
|
||||
}
|
||||
|
||||
/* ---- Публичный API ------------------------------------------------ */
|
||||
int pop_ctrl_init(void)
|
||||
int pop_ctrl_init(void) __banked
|
||||
{
|
||||
control_forward = control_backward = control_up = control_down = CONTROL_RELEASED;
|
||||
control_shift2 = CONTROL_RELEASED;
|
||||
@@ -682,17 +683,17 @@ int pop_ctrl_init(void)
|
||||
return kbd_raw_open();
|
||||
}
|
||||
|
||||
void pop_ctrl_close(void)
|
||||
void pop_ctrl_close(void) __banked
|
||||
{
|
||||
kbd_raw_close();
|
||||
}
|
||||
|
||||
int8_t pop_ctrl_shift_held(void)
|
||||
int8_t pop_ctrl_shift_held(void) __banked
|
||||
{
|
||||
return (int8_t)(control_shift == CONTROL_HELD);
|
||||
}
|
||||
|
||||
void pop_ctrl_tick(void)
|
||||
void pop_ctrl_tick(void) __banked
|
||||
{
|
||||
kbd_raw_sync(); /* снять залипшее после Rx-overrun SIO */
|
||||
/* control_kid (seg006:0CD1), ПЕРВАЯ строка: HP кончились — персонаж
|
||||
|
||||
Reference in New Issue
Block a user