Мигание тени: кадр приходил из кэша, а снимок писался по Guard.frame

Тень на уровне 6 стояла на двух страницах дабл-буфера в разных позах.
Отрисовка брала image из кэша kid_frame/pop_gframe, который наполняет тик,
а снимок пропуска кадра писала по Char.frame — расхождение застревало
навсегда, потому что снимок совпадал и страница больше не перерисовывалась.

Кадр теперь грузит сама отрисовка, как в оригинале (add_*_to_objtable →
load_fram_det_col, seg008:22F0/2324).  Разбор — BUGS_CLOSED.md.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
2026-08-18 11:48:45 +03:00
parent 89b603ae04
commit 085a198c20
3 changed files with 131 additions and 11 deletions
+19 -7
View File
@@ -198,20 +198,32 @@ static void load_frame(void)
* в остальных она ходит кадрами Кида (seg006:532). */
const uint8_t *f;
uint8_t use_guard_tbl = pop_frame_tbl_is_guard(Char.charid, Char.frame);
f = 0;
if (use_guard_tbl) {
int16_t idx = (int16_t)Char.frame;
if (idx >= 102 && idx < 107) idx += 70;
idx -= 149;
if (idx < 0 || idx >= KID_NGFRAMES) { cur_frame.image = 255; return; }
f = kd_gframe_ptr((uint8_t)idx);
if (idx >= 0 && idx < KID_NGFRAMES) f = kd_gframe_ptr((uint8_t)idx);
} else {
f = kd_frame_ptr(Char.frame);
}
cur_frame.image = f[0];
cur_frame.dx = (int8_t)f[1];
cur_frame.dy = (int8_t)f[2];
cur_frame.flags = f[3];
cur_frame.sword = f[4];
if (f) {
cur_frame.image = f[0];
cur_frame.dx = (int8_t)f[1];
cur_frame.dy = (int8_t)f[2];
cur_frame.flags = f[3];
cur_frame.sword = f[4];
} else {
/* Кадра нет в таблице — оригинал кладёт blank_frame {255,0,0,0,0}
* (get_frame_internal, seg006:507) и этим ГАСИТ отрисовку. Выход
* ОДИН на обе ветки: «пусто» обязано доехать и до кэша владельца
* (ниже), иначе kid_frame/pop_gframe держат ПРОШЛУЮ картинку и
* вместо «не рисовать» рисуется она — тот же класс, что
* BUG-SHADOW-STALE-FRAME (разбор в pop_char_draw). */
cur_frame.image = 255;
cur_frame.dx = cur_frame.dy = 0;
cur_frame.flags = cur_frame.sword = 0;
}
/* Кэш кадра для ОТРИСОВКИ раскладываем ЗДЕСЬ, по charid активного
* персонажа, а не в save*-функциях. Раньше кэш писали pop_savekid/
* pop_saveshad, и любое окно Char БЕЗ play_seq (окна боёвки