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

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> MenuBack  : register(t100);
Texture2D<float4> MenuPlate : register(t101);
Texture2D<float4> MenuFrontShadow : register(t102);
float2 RotateUV(float2 uv, float angle)
{
    float s = sin(angle);
    float c = cos(angle);

    // rotate around center (0.5, 0.5)
    uv -= 0.5;
    uv = float2(
        uv.x * c - uv.y * s,
        uv.x * s + uv.y * c
    );
    uv += 0.5;

    return uv;
}

void main(VertexOut pIn, out float4 color : SV_Target0)
{
    float Speed = -0.001;
    float2 PlateScale = float2(0.5f, 1.2f);
    uint w, h;
    MenuBack.GetDimensions(w, h);
    if (w == 0 || h == 0) discard;

    float2 uv = pIn.texCoord;
    uv.y = 1.0f - uv.y;
    
    // Background
    float4 back = MenuBack.Load(int3(uv * float2(w, h), 0));
    
    // --- Plate transform ---
    float2 uvr = uv;
    uvr.x *= 0.4;
    uvr.y *= 1.0;
    const float angle = radians(30.0f);

    // Direction vector from rotation
    float2 dir = float2(cos(angle*2.45), sin(angle*2.45));

    // Motion offset
    float2 motion = dir * FRAME_INDEX * Speed;
    float anglefix = angle / 1.82;
    float2 plateUV = uvr - motion;
    plateUV = RotateUV(plateUV, anglefix);

    // Sample plate (bounds check)
    float4 plate = float4(0,0,0,0);
    if (all(plateUV >= 0.0f) && all(plateUV <= 1.0f))
    {
        plate = MenuPlate.Load(int3(plateUV * float2(w, h)* float2(2.5, 1.0), 0));
    }

    motion = dir * (FRAME_INDEX-1000) * Speed;
    plateUV = uvr - motion;
    plateUV = RotateUV(plateUV, anglefix);
    // Sample plate (bounds check)
    float4 plate2 = float4(0,0,0,0);
    if (all(plateUV >= 0.0f) && all(plateUV <= 1.0f))
    {
        plate2 = MenuPlate.Load(int3(plateUV * float2(w, h)* float2(2.5, 1.0), 0));
    }

    motion = dir * (FRAME_INDEX+1000) * Speed;
    plateUV = uvr - motion;
    plateUV = RotateUV(plateUV, anglefix);
    // Sample plate (bounds check)
    float4 plate3 = float4(0,0,0,0);
    if (all(plateUV >= 0.0f) && all(plateUV <= 1.0f))
    {
        plate3 = MenuPlate.Load(int3(plateUV * float2(w, h)* float2(2.5, 1.0), 0));
    }
    // Alpha blend
    float4 rescol = plate + plate2 + plate3;
    
    float4 front = MenuFrontShadow.Load(int3(uv * float2(w, h), 0));
    rescol.a = rescol.a*ceil(front.a);

    color = lerp(back, rescol, rescol.a);
    color.rgb *= front.rgb + (1.0-front.a*0.6);
}

#endif

