// Shared 68k emit-time helpers: chunky->planar column conversion and
// big-endian opcode-word emission. Included (as static functions) by
// the two 68k emitters -- spriteEmitPlanar68k.c (Amiga) and
// spriteEmitInterleaved68k.c (ST) -- so the c2p pixel walk that must
// match the interpreted planes walkers bit-for-bit (jlpSpriteDrawPlanes
// on Amiga, stSpriteDrawByteAligned on ST) exists exactly once.
//
// Emit-time only (jlSpriteCompile), never on a draw hot path, so plain
// static functions are acceptable here despite the general
// macros-over-inline preference for shared headers.

#ifndef JOEYLIB_SPRITE_EMIT_C2P_H
#define JOEYLIB_SPRITE_EMIT_C2P_H

#include <stdint.h>

#include "spriteInternal.h"


static void     c2pColumn(const uint8_t *trp, uint8_t plane[4], uint8_t *opaqueOut);
static uint32_t putWord(uint8_t *out, uint32_t cursor, uint16_t w);


// Convert one 8-pixel sprite tile column (4 chunky 4bpp bytes) into 4
// plane bytes plus an opaque mask, bit 7 = leftmost pixel. Pixel order
// is hi(b0),lo(b0),hi(b1),lo(b1),hi(b2),lo(b2),hi(b3),lo(b3) at bit
// positions 7..0.
static void c2pColumn(const uint8_t *trp, uint8_t plane[4], uint8_t *opaqueOut) {
    uint8_t opaque;
    uint8_t i;

    plane[0] = 0u;
    plane[1] = 0u;
    plane[2] = 0u;
    plane[3] = 0u;
    opaque   = 0u;
    for (i = 0u; i < 8u; i++) {
        uint8_t nibble;
        uint8_t bit;

        nibble = (i & 1u) ? (uint8_t)(trp[i >> 1] & 0x0Fu)
                          : (uint8_t)(trp[i >> 1] >> 4);
        if (nibble != TRANSPARENT_NIBBLE) {
            bit    = (uint8_t)(0x80u >> i);
            opaque = (uint8_t)(opaque | bit);
            if (nibble & 1u) { plane[0] = (uint8_t)(plane[0] | bit); }
            if (nibble & 2u) { plane[1] = (uint8_t)(plane[1] | bit); }
            if (nibble & 4u) { plane[2] = (uint8_t)(plane[2] | bit); }
            if (nibble & 8u) { plane[3] = (uint8_t)(plane[3] | bit); }
        }
    }
    *opaqueOut = opaque;
}


// Append a big-endian 16-bit word at cursor; returns the new cursor.
static uint32_t putWord(uint8_t *out, uint32_t cursor, uint16_t w) {
    out[cursor]      = (uint8_t)(w >> 8);
    out[cursor + 1u] = (uint8_t)(w & 0xFFu);
    return cursor + 2u;
}

#endif
