e1ee447b7f
Раскладка (по подтверждённой пробником модели, tests/w3bankgfx): - roomtest переведён на MEMORY=huge: та же small-раскладка резидента (CODE в W1, DATA за ним) плюс банки кода в W3; - guards.c собирается как --bank 1=guards.c — там будет ИИ и боёвка; - СОСТОЯНИЕ стража живёт в W1/W2 (pop_guard.c): писучие статики __banked-модуля линкуются в страницу банка и снаружи не читаются, так что банк — только код; - поля pop_char_t повторяют char_type оригинала (types.h:302), чтобы порт seg005/seg006 ложился один в один. Режим читов (порт cheats_enabled, seg000:111): глобальный флаг pop_cheats, на время разработки включается в main. Реализован один чит — K (kill guard, seg000:786): скелета не берёт, живому стражу ставит guardhp_delta = -guardhp_curr и alive = 0. Обработка по фронту нажатия. Остальные читы оригинала не портированы. Проверено в MAME: приложение в huge-раскладке стартует, комната рисуется, Kid бегает — то есть банкованный pop_guard_tick() зовётся каждый кадр через трамплин и корректно возвращается; K не роняет приложение (стража в комнате пока нет). Банк занят на 6 Б из 16384. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
62 lines
2.6 KiB
C
62 lines
2.6 KiB
C
/*
|
|
* pop_guard.h — СОСТОЯНИЕ стража и точки входа в его логику.
|
|
*
|
|
* Разделение по окнам (docs/layout_plan_v2.md §4, подтверждено пробником
|
|
* tests/w3bankgfx):
|
|
* - СОСТОЯНИЕ живёт здесь, в W1/W2. Писучие статики __banked-модуля
|
|
* линкуются В СТРАНИЦУ БАНКА и снаружи не читаются, поэтому банк —
|
|
* только код;
|
|
* - ЛОГИКА (ИИ, боёвка) — в guards.c, собираемом как --bank 1=guards.c;
|
|
* - ОТРИСОВКА стража — из W1/W2 (рядом с kid_draw): из банка примитивы
|
|
* libbgi звать можно, но резидент W3 (pop_bg) — нельзя, поэтому слой
|
|
* фона/окклюзии за стража делает главный цикл.
|
|
*
|
|
* Поля char_type — как в оригинале (types.h:302), чтобы порт seg005/seg006
|
|
* ложился один в один.
|
|
*/
|
|
#ifndef POP_GUARD_H
|
|
#define POP_GUARD_H
|
|
|
|
#include <stdint.h>
|
|
|
|
/* charids (types.h:320) — нужны хотя бы для «скелет не убивается читом». */
|
|
#define CHARID_0_KID 0
|
|
#define CHARID_1_SHADOW 1
|
|
#define CHARID_2_GUARD 2
|
|
#define CHARID_4_SKELETON 4
|
|
#define CHARID_5_PRINCESS 5
|
|
|
|
typedef struct {
|
|
uint8_t frame;
|
|
uint8_t x, y;
|
|
int8_t direction;
|
|
int8_t curr_col, curr_row;
|
|
uint8_t action;
|
|
int8_t fall_x, fall_y;
|
|
uint8_t room;
|
|
uint8_t repeat;
|
|
uint8_t charid;
|
|
uint8_t sword;
|
|
int8_t alive; /* -1 = жив (как в оригинале), 0 = убит */
|
|
uint16_t curr_seq;
|
|
} pop_char_t;
|
|
|
|
extern pop_char_t Guard; /* страж ТЕКУЩЕЙ комнаты (как в оригинале) */
|
|
extern uint8_t guardhp_curr, guardhp_max;
|
|
extern int8_t guardhp_delta; /* <0 = в этом кадре отняли HP */
|
|
|
|
/* Есть ли живой страж в отрисованной комнате (для главного цикла). */
|
|
uint8_t pop_guard_present(void);
|
|
|
|
/* Убрать стража со сцены (смена комнаты / инициализация). */
|
|
void pop_guard_reset(void);
|
|
|
|
/* Чит «убить стража» (seg000:786, K): скелета не берёт. Вызывать только
|
|
* при включённых читах — проверку делает вызывающий. */
|
|
void pop_guard_kill(void);
|
|
|
|
/* Тик логики стража — В БАНКЕ (guards.c). Состояние берёт отсюда. */
|
|
void pop_guard_tick(void) __banked;
|
|
|
|
#endif
|