Клинок расширяет футпринт перерисовки на колонку (redraw_at_char)

Порт seg003:0430 «If char is holding sword, it makes redraw-area bigger»:
при Char.sword >= sword_2_drawn футпринт расширяется на одну колонку в
сторону взгляда (вправо при dir>=0, влево иначе).  У нас char_footprint
этого не делал, и клинок торчал на колонку дальше области, где
перерисовываются передние грани: меч оставался поверх столба, а его след
— на фоне.

char_footprint получил параметр sword; pop_fore_over_char — тоже (страж
машет мечом ровно так же).  Ветка Кида берёт Kid.sword, ветка стража —
Guard.sword.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
Александр Петров
2026-08-04 13:15:34 +03:00
parent e67117219f
commit 3164065243
3 changed files with 15 additions and 6 deletions
+13 -4
View File
@@ -19,6 +19,7 @@
#include "pop_geom.h" #include "pop_geom.h"
#include "pop_level.h" /* pop_doorlink2 — состояние нажатия кнопки */ #include "pop_level.h" /* pop_doorlink2 — состояние нажатия кнопки */
#include "pop_kid.h" /* Kid.curr_col/curr_row — порядок оверлеев (см. ниже) */ #include "pop_kid.h" /* Kid.curr_col/curr_row — порядок оверлеев (см. ниже) */
#include "pop_guard.h" /* SWORD_2_DRAWN — расширение футпринта под клинок */
/* ---- Атласы (прямая адресация) ------------------------------------- */ /* ---- Атласы (прямая адресация) ------------------------------------- */
static atlas_t env[5]; static atlas_t env[5];
@@ -1547,7 +1548,7 @@ static void other_overlay_tile(int row, int col)
static int8_t fp_cL, fp_cR, fp_cLraw, fp_rT, fp_rB, fp_rTraw; static int8_t fp_cL, fp_cR, fp_cLraw, fp_rT, fp_rB, fp_rTraw;
static void char_footprint(int obj_x, int obj_y, uint16_t w, uint16_t h, static void char_footprint(int obj_x, int obj_y, uint16_t w, uint16_t h,
int8_t dir) int8_t dir, uint8_t sword)
{ {
int wh = (int)((w + 1) >> 1); /* char_width_half */ int wh = (int)((w + 1) >> 1); /* char_width_half */
int xl = obj_x / 2 + 58; /* char_x_left (58-база) */ int xl = obj_x / 2 + 58; /* char_x_left (58-база) */
@@ -1558,6 +1559,14 @@ static void char_footprint(int obj_x, int obj_y, uint16_t w, uint16_t h,
cLraw = col_from_x(xl); /* до клампа: <0 = футпринт за левым швом */ cLraw = col_from_x(xl); /* до клампа: <0 = футпринт за левым швом */
cL = cLraw; if (cL < 0) cL = 0; else if (cL > 9) cL = 9; cL = cLraw; if (cL < 0) cL = 0; else if (cL > 9) cL = 9;
cR = col_from_x(xr); if (cR < 0) cR = 0; else if (cR > 9) cR = 9; cR = col_from_x(xr); if (cR < 0) cR = 0; else if (cR > 9) cR = 9;
/* redraw_at_char (seg003:0430): «If char is holding sword, it makes
* redraw-area bigger» — КЛИНОК торчит на колонку дальше габарита кадра,
* и без этого расширения передние грани в той колонке не
* перерисовываются: меч остаётся поверх столба, а его след — на фоне. */
if (sword >= SWORD_2_DRAWN) {
if (dir >= 0) { if (++cR > 9) cR = 9; }
else { if (--cL < 0) cL = 0; }
}
/* Порт set_char_collision (seg006:0723): нижний ряд = y_to_row_mod4(obj_y), /* Порт set_char_collision (seg006:0723): нижний ряд = y_to_row_mod4(obj_y),
* причём обёртка -1 (Kid НИЖЕ комнаты — climbdown/провал, obj_y в полосе * причём обёртка -1 (Kid НИЖЕ комнаты — climbdown/провал, obj_y в полосе
* «ряд 3») трактуется как ряд 3, НЕ ряд 0. Верхний ряд считается от * «ряд 3») трактуется как ряд 3, НЕ ряд 0. Верхний ряд считается от
@@ -1589,7 +1598,7 @@ void pop_fore_over_kid(int obj_x, int obj_y, uint16_t w, uint16_t h,
{ {
int8_t cL, cR, cLraw, rT, rB, rTraw, r, c; int8_t cL, cR, cLraw, rT, rB, rTraw, r, c;
fclip_on = 1; /* окно = прямоугольник спрайта */ fclip_on = 1; /* окно = прямоугольник спрайта */
char_footprint(obj_x, obj_y, w, h, dir); char_footprint(obj_x, obj_y, w, h, dir, Kid.sword);
cL = fp_cL; cR = fp_cR; cLraw = fp_cLraw; cL = fp_cL; cR = fp_cR; cLraw = fp_cLraw;
rT = fp_rT; rB = fp_rB; rTraw = fp_rTraw; rT = fp_rT; rB = fp_rB; rTraw = fp_rTraw;
/* set_objtile_at_char (seg006:1833): тайл, при обработке которого спрайт /* set_objtile_at_char (seg006:1833): тайл, при обработке которого спрайт
@@ -1673,11 +1682,11 @@ void pop_fore_over_kid(int obj_x, int obj_y, uint16_t w, uint16_t h,
* (seq_77..seq_84). Появятся падающие/висящие стражи — тогда и общий * (seq_77..seq_84). Появятся падающие/висящие стражи — тогда и общий
* порт redraw_at_char2, а не догадки сейчас. */ * порт redraw_at_char2, а не догадки сейчас. */
void pop_fore_over_char(int obj_x, int obj_y, uint16_t w, uint16_t h, void pop_fore_over_char(int obj_x, int obj_y, uint16_t w, uint16_t h,
int8_t dir) __banked int8_t dir, uint8_t sword) __banked
{ {
int8_t r, c; int8_t r, c;
fclip_on = 1; /* окно = прямоугольник спрайта */ fclip_on = 1; /* окно = прямоугольник спрайта */
char_footprint(obj_x, obj_y, w, h, dir); char_footprint(obj_x, obj_y, w, h, dir, sword);
gfx_set_bank(GFX_BANK_SPRITE); gfx_set_bank(GFX_BANK_SPRITE);
for (r = fp_rT; r <= fp_rB; r++) for (r = fp_rT; r <= fp_rB; r++)
for (c = fp_cL; c <= fp_cR; c++) for (c = fp_cL; c <= fp_cR; c++)
+1 -1
View File
@@ -78,7 +78,7 @@ void pop_fore_set_clip(int x, int y, int w, int h) __banked;
* вызов стал кроссбанковым и обязан идти через трамплин. Зовётся раз в * вызов стал кроссбанковым и обязан идти через трамплин. Зовётся раз в
* кадр, других вызывающих нет — цена одного трамплина здесь не видна. */ * кадр, других вызывающих нет — цена одного трамплина здесь не видна. */
void pop_fore_over_char(int obj_x, int obj_y, uint16_t w, uint16_t h, void pop_fore_over_char(int obj_x, int obj_y, uint16_t w, uint16_t h,
int8_t dir) __banked; int8_t dir, uint8_t sword) __banked;
/* Восстановить фон там, где в прошлых кадрах рисовался ОВЕРЛЕЙ /* Восстановить фон там, где в прошлых кадрах рисовался ОВЕРЛЕЙ
* (draw_other_overlay/floor_overlay/полоса потолка): он выходит за * (draw_other_overlay/floor_overlay/полоса потолка): он выходит за
+1 -1
View File
@@ -157,7 +157,7 @@ void pop_guard_draw(void) __banked
* (seg008:690 draw_tile_fore). Без этого страж виден сквозь передний * (seg008:690 draw_tile_fore). Без этого страж виден сквозь передний
* столб. */ * столб. */
if (w && h) if (w && h)
pop_fore_over_char(fp_x, obj_y, w, h, Guard.direction); pop_fore_over_char(fp_x, obj_y, w, h, Guard.direction, Guard.sword);
} }
/* ---- Индикаторы HP (порт draw_kid_hp / draw_guard_hp, seg000:1416) --- * /* ---- Индикаторы HP (порт draw_kid_hp / draw_guard_hp, seg000:1416) --- *