Резидент: pop_kid/pop_guard/main расколоты по частоте вызова (куча 6669 Б)
MEM-COLD3, шаги 3-5. Кандидаты выбирались не по размеру, а по тому, КТО зовёт: если единственный вызывающий уже в банке, код едет к нему и трамплин не появляется вовсе. * pop_kdraw.c -> БАНК 4 (к pop_cdraw.c): клинок в руке (pop_sword_draw) и блит спрайта chtab_2 по id (pop_kid_img_blit). Оба звал ровно pop_cdraw, теперь вызовы прямые — контракт и условие корректности в _pop_kdraw.h. * pop_kboot.c -> БАНК 8: загрузка атласов Кида и страницы kid_data.bin (раз за игру). Дескриптор страницы — _pop_kid.h. * pop_guard_cold.c -> БАНК 8: страж идёт за Кидом + вход стража в комнату. Оба зовёт roomtest_cold.c из того же банка — снова без трамплина. * Из main в банк 8 уехали pop_boot (загрузка ресурсов, палитра, первый экран), pop_level_switch (смена уровня) и pop_shutdown. FIRST_LEVEL переехал в pop_tune.h — константа нужна обеим половинам цикла. _CODE 23005 -> 19861, куча 3525 -> 6669 Б. Банк 8 — 6.5 из 16 КБ. tests-host 6/6 (в наборы добавлены eng_pop_kboot и eng_pop_guard_cold).
This commit is contained in:
@@ -22,6 +22,9 @@
|
||||
#include "pop_cdraw.h" /* pop_cd — инвалидация слотов после переворота */
|
||||
#include <sprite.h> /* gfx_copy_page */
|
||||
#include "pop_tune.h"
|
||||
#include "pop_cheat.h" /* pop_cheats — режим разработки включает pop_boot */
|
||||
#include <stdio.h> /* puts/printf — сообщения об ошибках загрузки */
|
||||
#include <kbd_raw.h>
|
||||
|
||||
#define SEQ_STAND 2
|
||||
#define SEQ_TURN 5
|
||||
@@ -529,3 +532,121 @@ void pop_flip_screen(void) __banked
|
||||
POP_CD_TOUCH_ALL(); /* фон трогали целиком */
|
||||
pop_hp_invalidate(); /* полосу HP перерисовать */
|
||||
}
|
||||
|
||||
/* ---- Запуск, смена уровня, завершение ------------------------------- *
|
||||
* Три куска главного цикла, которые отрабатывают раз за игру (или раз на
|
||||
* уровень). В резиденте от них оставались только вызовы — сам код здесь.
|
||||
*/
|
||||
|
||||
int pop_boot(void) __banked
|
||||
{
|
||||
/* Набор фона — по типу СТАРТОВОГО уровня. Атласы грузятся ДО initgraph
|
||||
* (тот снимает DSS-страницу W0); уровень к этому моменту ещё не прочитан,
|
||||
* поэтому тип берём напрямую от номера. */
|
||||
pop_current_level = FIRST_LEVEL;
|
||||
if (pop_bg_load(pop_level_type()) != 0) {
|
||||
puts("pop_bg_load failed");
|
||||
return -1;
|
||||
}
|
||||
pop_cheats = 1; /* режим разработки: читы включены */
|
||||
pop_guard_reset();
|
||||
if (pop_kid_data_load("KID\\kid_data.bin") != 0) { /* кадры+seqtbl в EMM-странице */
|
||||
printf("kid_data.bin load failed\n");
|
||||
return -1;
|
||||
}
|
||||
pop_sword_load(); /* меч в руке (без него кадры 229+ без клинка) */
|
||||
pop_guard_load(); /* атласы стража (GUARD\\g0..g4) */
|
||||
if (pop_kid_load(28) != 0) { /* ВСЕ страницы: бег+стоп+разворот+присед+прыжок */
|
||||
puts("kid atlas load failed");
|
||||
return -1;
|
||||
}
|
||||
if (pop_level_load_num(FIRST_LEVEL) != 0) { /* сырой уровень в EMM-страницу */
|
||||
puts("level load failed");
|
||||
return -1;
|
||||
}
|
||||
pop_next_level = pop_current_level; /* current_level = next_level (load_lev_spr) */
|
||||
pop_kid_hp_newgame(); /* init_game: hitp_beg_lev = start_hitp */
|
||||
pop_checkpoint = 0; /* init_game (seg003:37) */
|
||||
|
||||
initgraph();
|
||||
gfx_set_visible_page(0);
|
||||
if (gfx_pal_fload(0, "KID\\kid.pal") < 0) /* единая игровая палитра */
|
||||
gfx_pal_fload(0, "a:\\kid.pal");
|
||||
gfx_pal_sync(); /* палитра 0 -> плоскость 1 */
|
||||
/* kid.pal — ЕДИНАЯ игровая палитра, собранная из VDUNGEON, и она только
|
||||
* что затёрла слоты тайлсета. Возвращаем цвета текущего набора: на
|
||||
* дворцовых уровнях без этого рисуется дворцовая геометрия подземельными
|
||||
* красками (сине-серое вместо песочного). */
|
||||
pop_bg_pal_apply();
|
||||
|
||||
/* Фон комнаты рисуется в ОБЕ графические страницы: у каждой своя
|
||||
* ОЗУ-копия/видео-ОЗУ, а heal берёт чистый фон из ОЗУ-копии ТОЙ
|
||||
* страницы, в которую рисуем. Дальше каждый тик восстанавливаем
|
||||
* ТОЛЬКО прямоугольник Кида (pop_char_heal), а не весь экран. */
|
||||
/* Извлечь и отрисовать стартовую комнату (в обе страницы). P0: сбросить
|
||||
* trob/room_modif (ленивая инициализация из уровня при первом входе). */
|
||||
/* Старт — ПО ДАННЫМ УРОВНЯ (комната/тайл/направление/поза входа), см.
|
||||
* pop_start_level. Управление: ←/→ бег, ↓ присед, ↑+→ прыжок с места,
|
||||
* Shift шаг, ESC — выход. Карта коллизии задана внутри enter_room. */
|
||||
pop_start_level();
|
||||
gfx_set_draw_page(0);
|
||||
pop_char_draw(POP_CH_KID);
|
||||
pop_char_fore(POP_CH_KID);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Порт play_level_2 (seg003:0386..0410) + play_level (seg003:81): цикл
|
||||
* уровня кончается, когда next_level разошёлся с current_level (END_LEVEL
|
||||
* после seq_70 в двери уровня либо чит Shift+L), и play_level грузит
|
||||
* следующий. Возврат -1 — фатально (не удалось сменить набор фона). */
|
||||
int pop_level_switch(void) __banked
|
||||
{
|
||||
|
||||
/* Порт play_level_2 (seg003:0386..0410) + play_level (seg003:81):
|
||||
* цикл уровня кончается, когда next_level разошёлся с
|
||||
* current_level (END_LEVEL после seq_70 в двери уровня либо чит
|
||||
* Shift+L), и play_level грузит следующий.
|
||||
*
|
||||
* HP переносится: hitp_beg_lev = hitp_max ДО загрузки — так
|
||||
* поднятая на уровне «жизнь» (большая склянка) переезжает
|
||||
* дальше, а урон — нет (do_startpos дольёт до потолка). */
|
||||
hitp_beg_lev = hitp_max;
|
||||
pop_checkpoint = 0; /* уровень пройден (seg003:413) */
|
||||
if (pop_level_load_num(pop_next_level) != 0) {
|
||||
pop_next_level = pop_current_level; /* файла нет — остаёмся */
|
||||
} else {
|
||||
/* Набор спрайтов соперника у каждого уровня СВОЙ
|
||||
* (load_lev_spr, seg000:1092): уровень 3 — скелет, у него и
|
||||
* кадров меньше, чем у стража. Без перезагрузки соперник
|
||||
* рисуется чужим атласом: часть индексов уходит за его
|
||||
* пределы, и персонаж просто не виден. */
|
||||
pop_guard_free();
|
||||
pop_guard_load();
|
||||
/* Тайлсет: подземелье <-> дворец (порт tbl_envir_ki,
|
||||
* seg000:1108). Внутри — no-op, если тип не менялся;
|
||||
* при смене выгружает старые атласы и правит 32 записи
|
||||
* палитры. Только на границе уровня, не в кадре. */
|
||||
if (pop_bg_load(pop_level_type()) != 0) {
|
||||
puts("bg set load failed");
|
||||
return -1;
|
||||
}
|
||||
/* Всё состояние прошлого уровня сносит сам pop_start_level:
|
||||
* pop_trob_reset обнуляет room_seen (модификаторы комнат
|
||||
* перечитаются из НОВОЙ страницы), тайлы/стражи приезжают
|
||||
* из неё же, loose чистит enter_room. */
|
||||
pop_start_level();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void pop_shutdown(void) __banked
|
||||
{
|
||||
gfx_set_idle_hook(0); /* снять хук ДО закрытия raw-канала */
|
||||
pop_ctrl_close();
|
||||
closegraph();
|
||||
pop_bg_free();
|
||||
pop_kid_free();
|
||||
pop_guard_free();
|
||||
pop_kid_data_free();
|
||||
pop_level_free();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user