Texture1D<float4> ConfigData : register(t120);

#define DIMENSIONS ConfigData[87].xy
#define SHIFT ConfigData[87].zw

#define FRAME_INDEX ConfigData[88].x  // Input for the current frame

// Hardcoded flipbook properties
#define FLIPBOOK_COLS 4  // Number of columns
#define FLIPBOOK_ROWS 16  // Number of rows

struct VertexOut {
    float4 position : SV_Position;
    float2 texCoord : TEXCOORD0;
};

#ifdef VERTEX_SHADER
void main(
    out VertexOut vOut,
    uint vIndex : SV_VertexID)
{
    float2 base, mod;
    mod.x = SHIFT.x * 2.0f - 1.0f;
    mod.y = (1.0f - SHIFT.y) * 2.0f - 1.0f;
    base = float2(DIMENSIONS.x * 2.0f, DIMENSIONS.y * -2.0f);
    
    float2 posArray[4] = {
        float2(base.x, base.y),
        float2(base.x, 0.0f),
        float2(0.0f, base.y),
        float2(0.0f, 0.0f)
    };
    
    float2 uvArray[4] = {
        float2(1.0f, 0.0f),
        float2(1.0f, 1.0f),
        float2(0.0f, 0.0f),
        float2(0.0f, 1.0f)
    };
    
    vOut.position.xy = posArray[vIndex] + mod;
    vOut.position.zw = float2(0.0f, 1.0f);
    vOut.texCoord = uvArray[vIndex];
}
#endif

#ifdef PIXEL_SHADER
Texture2D<float4> imageTex : register(t100);

void main(VertexOut pIn, out float4 color : SV_Target0)
{
    uint w, h;
    imageTex.GetDimensions(w, h);
    if (w == 0 || h == 0) discard;
    // Compute per-frame UV offset
    float col = fmod(round(FRAME_INDEX), FLIPBOOK_COLS);
    float row = floor(round(FRAME_INDEX) / FLIPBOOK_COLS);
    float2 frameSize = float2(1.0f / FLIPBOOK_COLS, 1.0f / FLIPBOOK_ROWS);
    float2 frameOrigin = float2(col * frameSize.x, row * frameSize.y);
    
    pIn.texCoord.y = 1.0f - pIn.texCoord.y;
    float2 frameUV = frameOrigin + pIn.texCoord * frameSize;

    color = imageTex.Load(int3(frameUV * float2(w, h), 0));
}
#endif
