/*
 * pop_redraw.c — пометки перерисовки тайлов и их разбор.  См. pop_redraw.h.
 *
 * Живёт в W1/W2 (НЕ в резиденте W3): пометки ставит логика, которая должна
 * оставаться достижимой из будущих __banked-модулей.  Сам разбор зовёт
 * pop_bg (резидент W3) — это законно, потому что разбор дёргает только
 * главный цикл.
 */
#include <stdint.h>
#include "pop_redraw.h"
#include "pop_bg.h"

#define NTILES 30
#define NCOLS  10

static uint8_t rd_kind[NTILES], rd_cnt[NTILES];
static uint8_t rda_kind[NCOLS], rda_cnt[NCOLS];
/* Сколько всего непустых пометок: без него проход по 40 ячейкам крутился бы
 * КАЖДЫЙ кадр впустую (замер 2026-07-27 на прежнем rest-цикле: ~12 % кадра). */
static uint8_t rd_pending;

void pop_redraw_reset(void)
{
    uint8_t i;
    for (i = 0; i < NTILES; i++) { rd_kind[i] = 0; rd_cnt[i] = 0; }
    for (i = 0; i < NCOLS;  i++) { rda_kind[i] = 0; rda_cnt[i] = 0; }
    rd_pending = 0;
}

void pop_set_redraw(uint8_t tilepos, uint8_t kind, uint8_t pages)
{
    if (tilepos >= NTILES) return;
    if (!rd_cnt[tilepos]) rd_pending++;
    rd_kind[tilepos] = kind;
    if (pages > rd_cnt[tilepos]) rd_cnt[tilepos] = pages;
}

void pop_set_redraw_above(uint8_t col, uint8_t kind, uint8_t pages)
{
    if (col >= NCOLS) return;
    if (!rda_cnt[col]) rd_pending++;
    rda_kind[col] = kind;
    if (pages > rda_cnt[col]) rda_cnt[col] = pages;
}

/* redraw_needed (seg008:0178): пройти пометки и нарисовать.  row/col ведём
 * бегущими счётчиками, а не через i/10 и i%10 — у Z80 нет деления, и SDCC
 * выносит __divuchar/__moduchar в вершину цикла как общее подвыражение
 * аргументов (30*2 делений за кадр даже когда рисовать нечего). */
void pop_redraw_needed(void)
{
    uint8_t i, row = 0, col = 0, left = 0;
    if (!rd_pending) return;
    for (i = 0; i < NTILES; i++) {
        if (rd_cnt[i]) {
            switch (rd_kind[i]) {
            case POP_RD_SPIKE:      pop_spike_redraw(row, col);      break;
            case POP_RD_LOOSE:      pop_loose_shake_draw(row, col);  break;
            case POP_RD_LOOSE_GONE: pop_loose_bake_empty(row, col);  break;
            case POP_RD_FLOOR:      pop_floor_bake(row, col);        break;
            case POP_RD_LEVELDOOR:  pop_leveldoor_redraw(row, col);  break;
            case POP_RD_GATE:       pop_gate_redraw(row, col);       break;
            default: break;
            }
            if (--rd_cnt[i]) left++;
            else             rd_kind[i] = 0;
        }
        if (++col == 10) { col = 0; row++; }
    }
    for (i = 0; i < NCOLS; i++) {
        if (rda_cnt[i]) {
            if (rda_kind[i] == POP_RDA_CEIL) pop_ceil_shake_draw(i);
            else                             pop_ceil_bake_empty(i);
            if (--rda_cnt[i]) left++;
            else              rda_kind[i] = 0;
        }
    }
    rd_pending = left;
}
