//HUD
// ---- Created with 3Dmigoto v0.6.164 on Thu Aug 14 12:41:50 2025

cbuffer _Globals : register(b0)
{
  float4 ucp0_ClipPlane : packoffset(c29);
  float4 d007_PosDecompressionScaleAndOffset : packoffset(c56);
}

// 3Dmigoto declarations
#define cmp -
Texture1D<float4> IniParams     : register(t120);
Texture2D<float4> StereoParams  : register(t125);
Texture2D<float>  DepthBuffer   : register(t110);

// ==================== CONFIG MANUAL DEL ICONO ====================
// Tamaño del atlas
static const float2 ATLAS_SIZE = float2(1024, 1024);

// Definición de múltiples iconos en píxeles (x0,y0,x1,y1)
// Añade más filas aquí si quieres más iconos
static const int NUM_RECTS = 2;
static const float4 RECTS_PX[NUM_RECTS] =
{
    float4(592, 381, 644, 397),   // Icono 1
    float4(59, 821, 118, 882)    // Icono 2
};

// Margen anti-bleeding
static const float PAD_PX = 0.0;

// (Opcional) compuerta de “cerca del centro de pantalla”
#define KEEP_CENTER_GATE 0
// ================================================================

static const float near = 0.0001;
static const float far  = 1;

float world_z_from_depth_buffer(float x, float y)
{
    uint width, height;
    float z;

    DepthBuffer.GetDimensions(width, height);

    // NDC [-1,1] -> texel coords [0..w-1],[0..h-1] (Y invertido)
    x = min(max((x * 0.5 + 0.5) * width,  0), width  - 1);
    y = min(max((-y * 0.5 + 0.5) * height, 0), height - 1);

    z = DepthBuffer.Load(int3(x, y, 0)).x;
    if (z == 1)
        return 0;

    // Linealización aproximada
    return (far * near / ((1 - z) * near) + (far * z));
}

float adjust_from_depth_buffer(float x, float y)
{
    float4 stereo = StereoParams.Load(0);
    if (stereo.x == 0) { return 0; }

    float separation  = stereo.x;
    float convergence = stereo.y;
    float old_offset, offset, w, sampled_w, distance;
    uint  i;

    offset   = (near - convergence) * separation; // Z = X offset from center
    distance = separation - offset;               // total to cover

    old_offset = offset;
    [loop]
    for (i = 0; i < 255; i++) {
        offset += distance / 255.0;

        // Depth para este punto sobre la línea:
        w = (separation * convergence * 10) / (separation - offset);

        sampled_w = world_z_from_depth_buffer(x + offset, y);
        if (sampled_w == 0)
            return separation;

        // Intersección
        if (w > sampled_w)
            break;

        old_offset = offset;
    }

    return old_offset;
}

// ================================================================
// Helper para comprobar múltiples rectángulos en el atlas
bool in_any_atlas_rect(float2 uvAtlas)
{
    bool hit = false;

    [unroll]
    for (int i = 0; i < NUM_RECTS; ++i)
    {
        float4 rp  = RECTS_PX[i];                 // (x0,y0,x1,y1) en píxeles
        float2 uv0 = (rp.xy + PAD_PX) / ATLAS_SIZE;
        float2 uv1 = (rp.zw - PAD_PX) / ATLAS_SIZE;

        bool inside = (uvAtlas.x >= uv0.x) && (uvAtlas.y >= uv0.y) &&
                      (uvAtlas.x <= uv1.x) && (uvAtlas.y <= uv1.y);

        hit = hit || inside;
    }
    return hit;
}
// ================================================================

void main(
  uint4 v0 : POSITION0,
  float4 v1 : COLOR0,
  float4 v2 : TEXCOORD0,
  out float4 o0 : SV_Position0,
  out float4 o1 : TEXCOORD0,
  out float4 o2 : TEXCOORD1,
  out float4 o3 : SV_ClipDistance0)
{
  float4 r0, r1;

  // Lecturas varias (como en tu VS original)
  float4 s             = StereoParams.Load(0);
  float4 texFilter     = IniParams.Load(int2(14,0));
  float  cursor_showing = IniParams[1].z;

  // --- Descompresión de posición empaquetada (original) ---
  r0.xyzw = (uint4)v0.xyzw;
  r1.xy = d007_PosDecompressionScaleAndOffset.ww * float2(1,256);
  r0.x = dot(r0.xy, r1.xy);
  r0.y = dot(r0.zw, r1.xy);
  r0.xy = d007_PosDecompressionScaleAndOffset.xy + r0.xy;
  r0.z = 1 + -r0.y;
  r0.xy = r0.xz * float2(2,2) + float2(-1,-1);

  // SV_Position
  o0.xy = r0.xy;
  o0.zw = float2(0,1);

  // Pasar UVs del atlas y atributo extra
  o1.xy = v2.xy;
  o1.zw = float2(0,0);
  o2.xyzw = v1.zyxw;

  // Clip distance
  r0.z = 1;
  o3.xyzw = dot(r0.xyz, ucp0_ClipPlane.xyw);

  // ===== Filtro: SOLO rectángulos definidos =====
  float2 uvAtlas = v2.xy;
  bool isAnyIcon = in_any_atlas_rect(uvAtlas);

  bool passCenter = true;
#if KEEP_CENTER_GATE
  passCenter = (abs(o0.y) < 0.5) && (abs(o0.x) < 0.5);
#endif

  if (texFilter.x == 15 && isAnyIcon && passCenter)
  {
      o0.x += adjust_from_depth_buffer(0, 0.2);
  }

  return;
}
