6673279cef992e6d0eaf2433bd3fd08e83add4e4
6 Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
6673279cef |
PoP: скелет уровня 3, цвета стражей, окклюзия соперника; кэш соседних комнат
Скелет (L3-SKEL, ассеты + механика): - pop_pack_guard.py получил параметр набора (GUARD/SKEL): атлас скелета poc/res/skel/g0..g3.atl (28 кадров), палитра — из его res750.pal (на ур. 3 curr_guard_color = 0, оригинал палитру не подменяет); - pop_guard_load выбирает набор по tbl_guard_type и перезагружается ПРИ СМЕНЕ УРОВНЯ (load_lev_spr, seg000:1092) — без этого скелет рисовался атласом стража и был невидим; - load_frame: charid_4_skeleton идёт по таблице стража (seg006:529), тень — только в кадрах 150..189. Пока ветка была одна (charid_2_guard), скелет получал image из таблицы Кида (180 при 28 спрайтах) и не рисовался; - check_skel (seg002:1042), ветка charid_4 в enter_guard, возрождение в комнате 3 при падении (seg002:252), autocontrol_skeleton; - leveldoor_open (seg007:456) — новый флаг, сбрасывается стартом уровня. Цвета стражей (BUG-GUARD-COLOR-1, закрыт): - все 7 палитр res10.bin -> pop_guard_pal.h, заливка 16 слотов по guards_color комнаты перед отрисовкой (set_chtab_palette, seg003:257). Проверено в MAME: ур. 2 комн. 11 = цвет 1, комн. 7 = цвет 3, полоса HP меняется вместе со стражем. Грабля: gfx_pal_load отдаёт указатель в BIOS, а тот читает только #4000-#BFFF — таблицу из банка копируем в стек. Кэш соседних комнат (BUG-SWORD-GHOST-1, закрыт): - pop_map кэширует fg соседей слева/справа ЦЕЛИКОМ и резолвит col -10..19. Было -2..11, дальше мнимая стена: луч видимости упирался в неё (страж после follow_guard в col 12), Кид прятал меч посреди боя и не мог достать обратно. +48 байт W2. Окклюзия соперника: - pop_fore_over_char получил проход other_overlay_tile (порядок midtable, seg008:1B06) и расширение перебора объединённым прямоугольником «персонаж + клинок + брызги» — падающий скелет больше не рисуется поверх кладки и верхней грани пола; - клип полем 192 строк (reset_obj_clip, seg006:0507) для спрайта, клинка (общий pop_sword_draw) и брызг — спрайт не залезает на полосу HP; - ROOMNAV после смерти Кида делает честный pop_start_level: телепорт «оживлял» мёртвого мимо старта уровня, оставляя живого скелета рядом с вернувшейся кучей костей. Ассеты чомпера (под L3-CHOMP): весь набор кадров в атласе явным списком (101-105 низ, 111-113 верх, 106-110 фронт, 114-123 кровь mono-силуэтом) — render_room анимированные тайлы пропускает, и в атласе не было ни одного. Число EMM-страниц не изменилось. Тесты: tests-host все 5 наборов зелёные, t_char вырос до 65 проверок (резолв колонок за краем комнаты, возрождение скелета); в testkit добавлен гард «код наехал на данные» (DATA_LOC). Доски: TASKS.md разнесён на TASKS_OPEN/TASKS_CLOSED, закрытые баги с разбором корней — в bug_closed.md; заведены DRAW-CHAR (отрисовка одна на всех Char, как физика после GUARD-PHYS) и L3-COLOR (зелёная кладка уровня 3: level_var_palettes = ресурс 20, есть в MSDOS/PRINCE.DAT). В roomtest.c временно оставлен автостоп на падении соперника (отладка падений скелета) — помечен ВРЕМЕННО. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> |
||
|
|
e36828ae6e |
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> |
||
|
|
61d4255091 |
testkit: модульные тесты под ucsim_z80 + планы покрытия
Обвязка для быстрых тестов plain-C логики: секунды вместо прогона в MAME, без образа диска. ucsim_z80 идёт в комплекте нашего SDCC — новых зависимостей нет. ПОЧЕМУ ПОД Z80, А НЕ ХОСТОВЫМ GCC. У SDCC z80 int 16 бит, у хоста 32, и расходится это НЕ в объявлениях, а в выражениях: integer promotion повышает операнды до int независимо от того, объявлены они как uint8_t или uint16_t. Перевод кода на фиксированные типы разницу не убирает — убирает только исполнение с z80-семантикой. Побочно проверяется кодогенерация SDCC и модули с inline-asm, которых хостовая сборка не видит в принципе. Устройство: crt0_ucsim.s (SP, зануление, main, halt), tcheck.* (итог в структуру в ОЗУ), run_ucsim.py (гоняет ucsim, дампит tc_result, печатает отчёт), host-tests.mk (общие правила). Вывода через printf нет: тестовый бинарь линкуется без Sprinter-libc. Через ucsim-simif не идём — номера его команд плавают между версиями, halt + dump работают везде. Наборы лежат РЯДОМ с проверяемым кодом, обвязка общая: testkit/t_selftest.c — самопроверка (sizeof(int)==2) applications/PoP/roomtest/tests-host/ — движок PoP Первый содержательный набор — t_geom: сверяет рукописный asm-LCG из pop_geom.c с наивной 32-битной формулой на 128 шагах. Заявка «бит-в-бит как в SDLPoP» до сих пор держалась на комментарии. Тест проверен мутацией: порча эталонной константы даёт красный. Планы дальнейшего покрытия: docs/host-tests-plan.md — libc и libbgi (не начато) applications/PoP/docs/host_tests_plan.md — движок PoP Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> |
||
|
|
d552cbaca9 |
docs: bug_list — только открытые баги; закрытые → bug_closed.md
Три Critical'а (BUG-1 провал на row 1 при боковом переходе, BUG-2 ping-pong при возврате, BUG-3 окклюзия climb-up на кнопке) висели непроверенными с 2026-07-21. Прогнал в MAME: - BUG-1 не воспроизводится: room6 → кнопка (0,2) → открытая решётка → переход влево даёт room8, y=55, curr_row=0. Заодно снят и сам диагноз записи — репроекция Y при БОКОВОМ переходе не нужна: goto_other_room (seg002.c:390) меняет только x, наш check_leave делает то же. - BUG-2 не воспроизводится: шов room2↔room3, четыре пересечения с разворотом сразу после входа — комната меняется ровно раз на пересечение. - BUG-3 закрыт фиксом tile_code_drawn от 2026-07-28 (это дубль уже записанного «спуск с кнопки»); оговорка про непереснятый подъём — в bug_closed.md. bug_list.md теперь только открытое (BUG-CEIL-1/2/3, BUG-OCCL-1, T-1, T-2, таблица обхода 24 комнат) + индекс с якорями. bug_closed.md — закрытое вместе с разбором корней (odd-pixel char_x, подстановка тайла кнопки, баг кодогенератора SDCC), он и есть главная ценность архива. TASKS.md: кросслинки на открытые баги в шапке, в L1-TRIAGE, L1-PASS и «Отложено». Указатели в CLAUDE.md/README/room_model_plan/layout_plan_v2 переведены на нужный из двух файлов. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> |
||
|
|
774b1cc7c4 |
docs(PoP): документация к актуальному статусу + план следующих уровней
Документы отстали от кода: PORT_PLAN писал «PoC не начат», хотя играется весь уровень 1, а четыре плана были исполнены целиком. - PORT_PLAN: таблица статусов по разделам; фазы 0-3 сделаны, 4-6 нет; риски §8 п.1/п.3 закрыты, п.2 переформулирован под реальный движок (спрайтовый движок для персонажей не используется, лимит «21 спрайт» неприменим), п.4 — найдено расхождение таймингов: оригинал считает логический кадр за 5 тиков при BASE_FPS=60 (83.3 мс, в бою 100 мс), а мы ждём три vsync (60 мс) — игра идёт примерно на 39 % быстрее эталона. - levels_plan.md — новый: машинерия перехода между уровнями, второй тайлсет (palace), потабличные различия и читы SDLPoP, которые окупаются сразу. Инвентарь тайлов снят прямо с res200N.bin: уровень 2 не требует ни одного нового ассета и ни одной новой механики. - roomtest/TASKS.md — новый: доска текущих задач с критериями готовности. - Удалены как исполненные и перекрытые кодом: clip_char_plan, double_buffer_plan, loose_floors_plan, size_optimization_plan. Его §8 (замеры скорости отрисовки) не был перекрыт — перенесён в layout_plan_v2 §9, чтобы не потерять цифры. - KID_PLAN / gates_spikes_plan — шапки «реализовано, оставлено справочником»; room_model_plan — «S1 сделан, остальное не срочно». - docs/README.md стал индексом с отметками актуальности. - ideas_backlog: зелье переворота экрана — оригинал переворачивает готовый буфер построчно, спрайты не трогает; по данным уровней тип 4 встречается только на уровне 9, до него механика не нужна. - examples/scroll: ссылка на удалённый план вела к неверному факту «теневая копия одна — общая»; заменено на подтверждённое «у каждой страницы своя». Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> |
||
|
|
8b30dc20c8 |
roomtest: loose-полы — тряска (knock), падение с окклюзией, фикс дабл-буфера
Проваливающиеся полы в roomtest (порт SDLPoP seg007/seg008), проверено в MAME: - Падающий кусок (mob): правый край env-42 (w=26, доходит до mob_x+57) теперь полностью покрыт heal-коридором (MOB_W 56->64) — убран тёмный хвост-тень на полу 2,7 ПОСЛЕ падения. - Окклюзия правого куска во ВРЕМЯ падения: после отрисовки плиты перерисовывается сосед-пол draw_tile(row,col+1) в том же кадре — край прячется за полом 2,7 (порт redraw_at_cur_mob: set_redraw_full+1). - Тряска от сотрясения (knock): seqtbl-команды KNOCK_DOWN/UP в play_seq -> флаг knock -> do_knock(ряд) трясёт loose ряда из покоя (modif=0x80). KNOCK_DOWN в land-seq (приземление) и runcyc (footstep). - Фикс «бесконечной тряски» (дабл-буфер): при завершении тряски (0x84->0) перерисовать покойный кадр плиты на ОБЕИХ страницах (loose_rest, 2 кадра) — иначе на одной странице застревает дрожащий кадр правой грани (живёт в тайлах col и col+1) -> мерцание через флип. Инфраструктура/документация: - app.mk: цель `make hdd` (упаковка в D: для MCP-моста MAME). - docs: POP-DAT-FormatSpecifications.pdf/.txt как каноническая спецификация форматов ресурсов; ссылки в README/MSDOS_RESOURCE_FORMAT. - README.md/CLAUDE.md для applications/PoP и roomtest (правило «SDLPoP — источник истины», порядок слоёв, режим отладки freeze 1/2). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> |