L2: переход между уровнями и игра уровня 2
Порт levels_plan.md §2 (шаг 1) — машинерия смены уровня целиком. - Номер уровня стал состоянием: pop_current_level (порт current_level), pop_next_level больше не флаг, а НОМЕР; главный цикл срабатывает по расхождению next != current (порт play_level_2, seg003:0386). - pop_level_load_num(n): LEVELS\res20NN.bin (fallback a:\), старая EMM-страница отпускается только после успешной загрузки новой. На диск кладутся все 15 уровней (34 КБ). - Потабличные различия (data.h:840..848) — таблицы по 16 в pop_level.c: tbl_entry_pose, tbl_guard_hp (HP стража ушло из хардкода 3), tbl_guard_type (−1 = стражей на уровне нет), tbl_level_type. - find_start_level_door (seg003:02E6): на уровне 2 стартовый тайл — правая половина двери уровня, без modif=43 + add_trob(...,3) Кид материализуется внутри глухой створки. Тип 3 = дверь захлопывается за спиной, как в оригинале. - HP через уровень: hitp_beg_lev (seg003) — рестарт уровня откатывает HP к нему, пройденный уровень подтягивает его к hitp_max. Заодно большая склянка add_life (тип зелья 2: +1 к потолку HP до 10) — на уровне 2 она есть, комната 20. - have_sword = level >= 2 (play_level, seg003:106). - Чит Shift+L — следующий уровень (seg000:698). Проверено в MAME: уровень 1 → Shift+L → уровень 2 (комната 5, новые для нас тайлы 8/9 «большая колонна» на месте, дверь захлопнута, HP 3) → влево в комнату 4 со стражем → Shift+L → уровень 3. Вход в стартовую дверь уровня 2 по Up не срабатывает — как и должно (start_room-гард). Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -98,6 +98,52 @@ void pop_level_free(void)
|
||||
if (lvl_ok) { mem_free_block(lvl_blk); lvl_ok = 0; }
|
||||
}
|
||||
|
||||
/* ---- Номер уровня и потабличные различия ---------------------------- */
|
||||
|
||||
uint8_t pop_current_level;
|
||||
|
||||
/* Таблицы из SDLPoP data.h:840..848, индекс = номер уровня (0 = демо).
|
||||
* Держим целиком по 16 байт: короче и дешевле любых «оптимизаций», а
|
||||
* расхождение с оригиналом сразу видно глазами. */
|
||||
static const uint8_t tbl_entry_pose[16] =
|
||||
{ 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0 };
|
||||
static const uint8_t tbl_guard_hp[16] =
|
||||
{ 4, 3, 3, 3, 3, 4, 5, 4, 4, 5, 5, 5, 4, 6, 0, 0 };
|
||||
static const int8_t tbl_guard_type[16] =
|
||||
{ 0, 0, 0, 2, 0, 0, 1, 0, 0, 0, 0, 0, 4, 3, -1, -1 };
|
||||
static const uint8_t tbl_level_type[16] =
|
||||
{ 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 1, 1, 0, 0, 1, 0 };
|
||||
|
||||
uint8_t pop_level_entry_pose(uint8_t n) { return n < 16 ? tbl_entry_pose[n] : 0; }
|
||||
uint8_t pop_level_guard_hp(uint8_t n) { return n < 16 ? tbl_guard_hp[n] : 3; }
|
||||
int8_t pop_level_guard_type(uint8_t n) { return n < 16 ? tbl_guard_type[n] : -1; }
|
||||
uint8_t pop_level_tileset(uint8_t n) { return n < 16 ? tbl_level_type[n] : 0; }
|
||||
|
||||
int pop_level_load_num(uint8_t n)
|
||||
{
|
||||
/* Имена патчим на месте, а не через sprintf: printf-семейство тянет в
|
||||
* резидент W1 форматтер, которого здесь больше негде применить. */
|
||||
static char pri[] = "LEVELS\\res2000.bin"; /* цифры — [12],[13] */
|
||||
static char alt[] = "a:\\res2000.bin"; /* цифры — [8],[9] */
|
||||
uint8_t saved_blk = lvl_blk, saved_page = lvl_page, saved_ok = lvl_ok;
|
||||
|
||||
if (n > 15) return -1;
|
||||
pri[12] = alt[8] = (char)('0' + n / 10);
|
||||
pri[13] = alt[9] = (char)('0' + n % 10);
|
||||
|
||||
/* Старую страницу отпускаем ТОЛЬКО после успешной загрузки новой:
|
||||
* pop_level_load сам аллоцирует страницу, и если файла нет — остаёмся
|
||||
* на текущем уровне вместо падения в пустой уровень. */
|
||||
lvl_ok = 0; /* чтобы pop_level_load не мешался */
|
||||
if (pop_level_load(pri) != 0 && pop_level_load(alt) != 0) {
|
||||
lvl_blk = saved_blk; lvl_page = saved_page; lvl_ok = saved_ok;
|
||||
return -1;
|
||||
}
|
||||
if (saved_ok) mem_free_block(saved_blk);
|
||||
pop_current_level = n;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Указатель на fg-тайлы комнаты r (1..24) в W0-пространстве (страница уже
|
||||
* замаплена вызывающим). */
|
||||
static const uint8_t *room_fg_ptr(uint8_t r)
|
||||
|
||||
Reference in New Issue
Block a user