Меню, статус-строка и оболочка игры: title/intro/cutscene/HoF, POP.CFG, палитры
Эта сессия (меню + текст в служебных полосах):
* Меню: рамка выделения считается от силуэта текста (SEL_PAD сверху и
снизу), а не «на глаз»; все экраны центрируются в игровых 200 строках
(UI_CENTER_TOP/UI_CENTER_FIELD) и в них помещаются; Enter и Space —
равноправные клавиши действия (ui_action_down).
* Settings: убраны SHOW SPRINTER SCREEN и BACK, добавлены DEBUG BAR и
ABOUT. About показывает тот же текст, что стартовый Sprinter screen,
минус строка про клавиши — общий about_text(), чтобы экраны не
разъехались. CONTROLS собирается таблицей и центрируется по
фактическому числу строк.
* GAME PAUSED переехала в нижнюю статус-строку, как в оригинале
(SDLPoP rect_bottom_text = {193,70,202,250}): это состояние программы,
а не пункт меню. POP_HP_Y вынесен в pop_cdraw.h — полосу делят два
модуля.
* pop_status.c (банк 9) — текст в обеих служебных полосах. Нижняя:
порт display_text_bottom + таймера (QUICKSAVE/QUICKLOAD/SOUND ON/OFF,
24 тика). Верхняя отладочная переведена с палочек на текст
«Level ##, Room ##, Speed: …, Sound: …, Immortal #» малым шрифтом, с
своим форматированием чисел (без printf и без деления).
Заявка сообщения — запись одного байта pop_status_msg: резидент W1/W2
не растёт, весь рендер в банке. Бюджет после правок не изменился
(_CODE 23981, куча 267 Б).
* Цена вывода: блит глифа ~4,6 тыс. тактов независимо от размера, поэтому
всё change-driven, отладочная строка перерисовывается ПО ПОЛЯМ, пробелы
не блитятся вовсе, а вход в комнату заливает только игровое поле
(pop_screen_fill_field) — борта от комнаты к комнате не меняются.
* Интро: в PV-сцене зазвучали пропавшие эффекты оригинала — закрытие
ворот (4) и открытие двери покоев (51), из которой входит Джафар.
* docs/status_line_text.md — полная инвентаризация ВСЕХ текстов SDLPoP в
статус-строке: геометрия, семантика text_time_total как идентификатора
сообщения, мигание, рестарт по истечении 36/288.
Вместе с этим выкладывается накопленная работа по оболочке полной игры:
автомат состояний (pop_app), title, intro/PV и cutscene, attract-demo,
Hall of Fame, глобальный таймер, настройки и POP.CFG, модуль палитр и
fade, звуковой набор, host-тесты на новые швы.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -17,6 +17,7 @@
|
||||
#include "_pop_draw.h" /* pop_onscreen_cols / pop_heal_fast */
|
||||
#include "pop_map.h" /* pop_clip_char_top (clip_char) */
|
||||
#include "pop_geom.h"
|
||||
#include "pop_level.h" /* POP_LEVEL_LAST — level 15 исключён */
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
#include <sprinter_mem.h>
|
||||
@@ -86,6 +87,17 @@ static const uint8_t *kd_gframe_ptr(uint8_t i)
|
||||
off += (uint16_t)(KD_DATA_OFF + KID_BIN_GFRAMES_OFF);
|
||||
return (const uint8_t *)off;
|
||||
}
|
||||
|
||||
/* ...и для таблицы кадров КАТСЦЕН (frame_tbl_cuts): по ней ходят Princess и
|
||||
* Vizier в сценах 8/9, финале и intro. Индекс — номер кадра как есть; какой
|
||||
* набор спрайтов рисовать, говорит поле sword (>>6: 1 = PV1, 2 = PV2). */
|
||||
static const uint8_t *kd_cframe_ptr(uint8_t i)
|
||||
{
|
||||
uint16_t off = (uint16_t)i;
|
||||
off += (uint16_t)(off << 2);
|
||||
off += (uint16_t)(KD_DATA_OFF + KID_BIN_CFRAMES_OFF);
|
||||
return (const uint8_t *)off;
|
||||
}
|
||||
#define KD_SEQ(cs) (*((const uint8_t *)(KD_DATA_OFF + KID_BIN_SEQTBL_OFF) + \
|
||||
(uint16_t)((cs) - SEQTBL_BASE)))
|
||||
/* Байт seqtbl по адресу оригинала (база SEQTBL_BASE); ТОЛЬКО под замапленной
|
||||
@@ -198,7 +210,10 @@ static void load_frame(void)
|
||||
const uint8_t *f;
|
||||
uint8_t use_guard_tbl = pop_frame_tbl_is_guard(Char.charid, Char.frame);
|
||||
f = 0;
|
||||
if (use_guard_tbl) {
|
||||
if (Char.charid == CHARID_5_PRINCESS || Char.charid == CHARID_6_VIZIER) {
|
||||
/* seg006:538 — у персонажей КАТСЦЕН своя таблица. */
|
||||
if (Char.frame < KID_NCFRAMES) f = kd_cframe_ptr(Char.frame);
|
||||
} else if (use_guard_tbl) {
|
||||
int16_t idx = (int16_t)Char.frame;
|
||||
if (idx >= 102 && idx < 107) idx += 70;
|
||||
idx -= 149;
|
||||
@@ -344,11 +359,11 @@ void play_seq(void)
|
||||
}
|
||||
break;
|
||||
case 0xF1: /* END_LEVEL: seq_70 доиграл — уровень пройден.
|
||||
* В оригинале это `++next_level`, а главный цикл
|
||||
* (play_level_2, seg003:0386) выходит, когда next_level
|
||||
* разошёлся с current_level. У нас так же: счётчик, а
|
||||
* решение — снаружи (roomtest.c). */
|
||||
pop_next_level++;
|
||||
* До 13-го это тот же `++next_level`, что в оригинале.
|
||||
* Level 15/copy protection вырезан: 14-й позже передаст
|
||||
* управление ENDING (FG11), но уже сейчас не может
|
||||
* породить запрос res2015.bin. */
|
||||
if (pop_next_level < POP_LEVEL_LAST) pop_next_level++;
|
||||
break;
|
||||
case 0xF3: /* GET_ITEM: аргумент 1 — применить эффект предмета
|
||||
* (порт play_seq -> proc_get_object, seg006) */
|
||||
|
||||
Reference in New Issue
Block a user