Атлас Тени: запечённый набор вместо спрайтов стража

Оригинал кладёт спрайт дважды — прозрачным блитом в x и XOR-блиттером в
x+1; пакетный блит так не умеет, поэтому результат запечён упаковщиком.
Две половины, как и у оригинала: sk* — кадры вне боя (спрайты Кида),
sf* — кадры 150..189 (SHADOW.DAT, тоже графика Кида).  251 спрайт,
32 EMM-страницы, палитра 16 цветов в 0xA0..0xAF.

Закрывает BUG-SHADOW-SET: раньше тип 4 уходил в guard_names, и Тень в
бою дралась серым стражем.

Грабля: kid.pal заливает все 256 записей и затирает слоты Тени —
палитра вынесена в pop_shadow_pal_apply рядом с pop_bg_pal_apply.

Проверено в MAME на 6-м уровне: силуэт с контуром, как в оригинале.
This commit is contained in:
2026-08-20 11:22:53 +03:00
parent e60a04e900
commit 30bcc3459b
41 changed files with 610 additions and 10 deletions
+24 -7
View File
@@ -23,6 +23,7 @@
#include "_pop_kdraw.h"
#include "pop_vflip.h" /* зеркальные страницы атласов (зелье инверсии) */ /* меч + блит по id — сосед по банку 4 */ /* атласы/кадр Кида, pop_sword_draw, окна Char */
#include "pop_cdraw.h"
#include "pop_shadow.h" /* запечённый набор Тени */
#include "pop_pace.h" /* pop_beam_sample — счёт кадров по лучу */
#include "pop_state.h" /* ВРЕМЕННО: зонды pop_dbg_b* */
#include "pop_bg.h" /* POP_YOFF, pop_fore_over_char, pop_fore_set_clip */
@@ -527,6 +528,10 @@ void pop_char_draw(uint8_t who) __banked
const pop_char_t *ch;
const kframe *fr;
const atlas_t *pages;
/* Атлас БРЫЗГ отдельно от кадра: у оригинала они всегда из «своего»
* chtab (Кид — chtab_2 image 218, прочие — chtab_5 image 1,
* seg006:2019), а у Тени кадр может прийти из другой половины набора. */
const atlas_t *spl;
const uint8_t *img;
uint8_t npages, page, idx, dp, flip, hurt, lskip;
uint8_t w, h, vis_w;
@@ -549,19 +554,31 @@ void pop_char_draw(uint8_t who) __banked
if (who == POP_CH_KID) {
pop_loadkid();
ch = &Kid; fr = &kid_frame; pages = kidp; npages = kid_npages;
spl = kidp;
hurt = pop_kid_hurt;
} else {
pop_loadshad();
ch = &Guard; fr = &pop_gframe; pages = gp;
npages = g_ok ? GUARD_PAGES : 0;
spl = gp;
hurt = pop_guard_hurt;
if (Guard.charid == 0) return; /* соперника на сцене нет */
/* ТЕНЬ (ур. 4) — это зеркальный Кид: вне боевых кадров 150..189 она
* ходит по таблице КИДА (seg006:0532), а `image` из неё индексирует
* спрайты Кида, а не стража. Набор атласов обязан идти за таблицей —
* условие берём из того же места, что load_frame, чтобы они не
* разъехались. */
if (!pop_frame_tbl_is_guard(Guard.charid, Guard.frame)) {
/* Набор атласов обязан идти за ТАБЛИЦЕЙ КАДРОВ — условие берём из
* того же места, что load_frame (seg006:0532), чтобы они не
* разъехались: вне боевых кадров 150..189 Тень ходит по таблице
* КИДА, и `image` из неё индексирует спрайты Кида. */
if (Guard.charid == CHARID_1_SHADOW && pop_shadow_kid_n) {
/* У Тени СВОЙ запечённый набор (pop_shadow.h): её вид даёт
* наложение спрайта на себя со сдвигом, а пакетный блит так не
* умеет. Обе половины лежат в нём же, поэтому подмены на kidp
* здесь уже не нужно. */
if (pop_frame_tbl_is_guard(Guard.charid, Guard.frame)) {
pages = pop_shadow_fgt; npages = pop_shadow_fgt_n;
} else {
pages = pop_shadow_kid; npages = pop_shadow_kid_n;
}
spl = pop_shadow_fgt; /* брызги — из половины chtab_5 */
} else if (!pop_frame_tbl_is_guard(Guard.charid, Guard.frame)) {
pages = kidp; npages = kid_npages;
}
}
@@ -741,7 +758,7 @@ void pop_char_draw(uint8_t who) __banked
/* по нему считается футпринт */
}
pop_dbg_m15(); /* ЗАМЕР: снимок прямоугольника сделан */
if (hurt) cd_splash(s, who, pages, fp_x, obj_y);
if (hurt) cd_splash(s, who, spl, fp_x, obj_y);
/* add_sword_to_objtable (seg006:1798): клинок отдельным спрайтом поверх
* персонажа — со своим прямоугольником heal. */
{