PoP roomtest: пики — редрой каждый кадр, полный draw_tile; пламя без heal
Выдвинутая пика живёт ТОЛЬКО в видео-ОЗУ (банк SPRITE, в запечённый фон не входит), а kid_heal каждый кадр возвращает под спрайтом Кида печёный фон — то есть стирает попавшие под него части остриёв. Редрой «только при смене видимой сигнатуры» их не возвращал: hold держится 15 кадров (modif 0x8F..0x81) с неизменным кадром 5. Итог по дампу VRAM (комната 14, Kid на (2,7), modif 0x8E): у спрайта 132 стёрто третье остриё (x 245..247), у 138 — прямое целиком (x 258..260) и низ наклонного, страницы дабл-буфера расходились на 8 пикселей. SDLPoP: animate_spike (seg007:0353) зовёт redraw_21h БЕЗУСЛОВНО, вне всяких if — редрой каждый кадр, пока trob жив. pop_spike_redraw переписан на честный redraw_tile_height (seg007:0218): heal + ПОЛНЫЙ draw_tile своего тайла и правого соседа. Рисовать только два спрайта остриёв нельзя — теряется порядок слоёв внутри тайла (draw_tile_anim_right идёт ПЕРВЫМ, база и fore соседа ложатся поверх), и остриё лезло на колонну (2,9). draw_tile заодно сам восстанавливает вклад соседних пик (ветка lcode==2), так что две пики подряд больше не гасят друг друга. Пламя факела: heal убран. Оригинал рисует его blitters_0_no_transp (seg008 draw_tile_anim_right), все 9 кадров лежат на общем канвасе 16x18 и бокс центрирован в ячейке — непрозрачный блит сам полностью накрывает предыдущий кадр. Кадры пакуются с opaque=True (POT_FLAME_IDS). Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -194,10 +194,11 @@ def load_indexed(chtab, id, opaque=False):
|
||||
return im.width, im.height, out
|
||||
|
||||
|
||||
def load_potion(id, mono=None):
|
||||
def load_potion(id, mono=None, opaque=False):
|
||||
"""chtab_1: res(150+id).png из data/PRINCE. mono=None — обычный спрайт
|
||||
(палитра chtab_1 -> слоты POT_PAL_BASE+i); mono=цвет — силуэт этим цветом
|
||||
(порт blitters_40h_mono)."""
|
||||
(порт blitters_40h_mono); opaque=True — пиксель 0 остаётся ЦВЕТОМ
|
||||
(порт blitters_0_no_transp, см. POT_FLAME_IDS)."""
|
||||
path = os.path.join(os.path.dirname(R.VDUNGEON_DIR), POT_DIR_NAME,
|
||||
f"res{150 + id}.png")
|
||||
if not os.path.exists(path):
|
||||
@@ -206,10 +207,12 @@ def load_potion(id, mono=None):
|
||||
if im.mode != "P":
|
||||
die(f"res{150+id}: mode {im.mode}, ожидался P")
|
||||
src = im.tobytes()
|
||||
if mono is None:
|
||||
out = bytes((0xFF if v == 0 else POT_PAL_BASE + v) for v in src)
|
||||
else:
|
||||
if mono is not None:
|
||||
out = bytes((0xFF if v == 0 else mono) for v in src)
|
||||
elif opaque:
|
||||
out = bytes((POT_PAL_BASE + v) for v in src)
|
||||
else:
|
||||
out = bytes((0xFF if v == 0 else POT_PAL_BASE + v) for v in src)
|
||||
return im.width, im.height, out
|
||||
|
||||
|
||||
@@ -399,6 +402,12 @@ def main():
|
||||
pot_entries[id] = load_potion(id, POT_BUBBLE_COLOR)
|
||||
elif id == POT_MASK_ID:
|
||||
pot_entries[id] = load_potion(id, POT_MASK_COLOR)
|
||||
elif id in POT_FLAME_IDS:
|
||||
# Пламя оригинал рисует blitters_0_no_transp (seg008
|
||||
# draw_tile_anim_right) — непрозрачным боксом поверх всего, что
|
||||
# сзади. Все 9 кадров лежат на одном канвасе 16x18, поэтому
|
||||
# непрозрачный блит сам стирает предыдущий кадр: heal не нужен.
|
||||
pot_entries[id] = load_potion(id, opaque=True)
|
||||
else:
|
||||
pot_entries[id] = load_potion(id)
|
||||
cnt, sz = pack_atlas(os.path.join(OUT_DIR, "pop_pot.atl"), pot_entries)
|
||||
|
||||
Reference in New Issue
Block a user