SprPoP: заставку можно прервать в любой её точке, F10 — выход
Три места, где нажатие раньше не работало или работало наполовину. FADE. fade_run() был замкнутым циклом на 2,13 с без опроса клавиш, а на стыке экранов их два: пропуск работал внутри сценария, но не между его шагами, и заставка ощущалась невыключаемой. Добавлены прерываемые варианты (pop_ui_fade_*_skip, обёртки в pop_pal) — отдельными функциями, а не флагом в прежних: в меню паузы и на переходе уровня прерывать нечего, и менять там поведение молча не следует. Прерванный fade всё равно доводит палитру до конца, экран не остаётся на промежуточной ступени. Подключено в интерпретаторе сценария, сцене с принцессой, четырёх катсценах cut_*, титрах и таблице рекордов. ПРОЯВЛЕНИЕ ПОЛОСАМИ. pop_screen_present_ltr() была void и нажатие ГЛОТАЛА: полосы схлопывались, картинка появлялась целиком — и всё, вызывающий о нажатии не узнавал. На заставке это выглядело как «клавиша срабатывает наполовину». Теперь возвращает признак прерывания, и он проброшен по маршруту: первый экран истории, титры финала, логотип между «свадьбой» и титрами. Везде считается КРОМКА нажатия от входа, как в сценах: клавиша, которой закончили предыдущий экран, ещё зажата, и принимать её за новое нажатие нельзя — иначе весь маршрут заставки схлопывался бы сам собой. F10 — НЕМЕДЛЕННЫЙ ВЫХОД, откуда угодно. Проверка стоит в kbd_idle(), а этот хук висит на gfx_wait_vsync, то есть вызывается везде, где программа ждёт кадр: заставка, титры, fade, проявление полосами, меню, игра. Одна точка вместо десятка по циклам ожидания. Флаг pop_quit_req резидентный — взводится и читается без трамплина из любого банка. Проверка в НАЧАЛЕ витка автомата обязательна: заставку прерывает любая клавиша, и без неё F10 успевал уронить программу в загрузку уровня перед закрытием. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -395,27 +395,43 @@ void pop_screen_present(uint8_t page) __banked
|
||||
* Страницы при этом НЕ меняются местами: копируем в видимую, как оригинал
|
||||
* копирует offscreen в onscreen. Поэтому у вызывающего после перехода на
|
||||
* ЭКРАНЕ и в скрытой странице лежит одно и то же. */
|
||||
void pop_screen_present_ltr(void) __banked
|
||||
/* Возвращает 1, если проявление прервано НОВЫМ нажатием.
|
||||
*
|
||||
* Раньше функция была void и нажатие ГЛОТАЛА: полосы схлопывались, картинка
|
||||
* появлялась целиком — и на этом всё, вызывающий о нажатии не узнавал. На
|
||||
* заставке это выглядело как «клавиша срабатывает наполовину»: проявление
|
||||
* прервалось, а в игру не ушли.
|
||||
*
|
||||
* Кромка считается от входа, как в сценах и в fade: клавиша, которой
|
||||
* закончили предыдущий экран, ещё зажата, и принимать её за новое нажатие
|
||||
* нельзя — иначе весь маршрут заставки схлопнулся бы сам собой. */
|
||||
uint8_t pop_screen_present_ltr(void) __banked
|
||||
{
|
||||
gfx_rect_t stripe;
|
||||
uint8_t visible = gfx_get_visible_page();
|
||||
uint8_t armed;
|
||||
int x;
|
||||
|
||||
kbd_raw_sync();
|
||||
armed = (uint8_t)!kbd_raw_any_down();
|
||||
gfx_set_draw_page(visible); /* source gfx_copy_page = target */
|
||||
stripe.y = 0;
|
||||
stripe.h = GFX_HEIGHT;
|
||||
for (x = 0; x < GFX_WIDTH; x += 4) {
|
||||
if (kbd_raw_any_down()) {
|
||||
kbd_raw_sync();
|
||||
if (!kbd_raw_any_down()) armed = 1;
|
||||
else if (armed) {
|
||||
/* Прервали — дорисовать остаток разом, а не бросить полукадр. */
|
||||
stripe.x = 0; stripe.w = GFX_WIDTH;
|
||||
gfx_copy_page(&stripe, GFX_COPY_DIRECT);
|
||||
return;
|
||||
return 1;
|
||||
}
|
||||
stripe.x = x;
|
||||
stripe.w = (uint16_t)((GFX_WIDTH - x < 4) ? GFX_WIDTH - x : 4);
|
||||
gfx_copy_page(&stripe, GFX_COPY_DIRECT);
|
||||
gfx_wait_vsync();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Нарисовать одну полосу и отпустить её страницу. Общая часть обоих
|
||||
|
||||
Reference in New Issue
Block a user