#include <metal_stdlib>
using namespace metal;

// shader 2baf9a8f53ba0bc9
// Shader dumped from BotW 208, using Cemu 2193a8c
// Based on 01ba1a725afa0b96_0000000000000000_vs.txt
// Night star (size)

constant float resScale = $height / 720.0;

#define SET_POSITION(_v)                                                       \
    out.position = _v;                                                         \
    out.position.z = (out.position.z + out.position.w) / 2.0
// start of shader inputs/outputs, predetermined by Cemu. Do not touch
struct SupportBuffer {};

struct UBuff1 {
    float4 d[4096];
};

struct UBuff2 {
    float4 d[8];
};

struct VertexIn {
    uint4 attrDataSem0 [[attribute(0)]];
};

struct VertexOut {
    float4 position [[position]] [[invariant]];
    float pointSize [[point_size]];
    float4 passParameterSem1 [[user(locn0)]];
    float4 passParameterSem2 [[user(locn1)]];
};

// end of shader inputs/outputs
template <typename TextureT, typename CoordT>
float sampleCompareEmulate(TextureT tex, sampler samplr, CoordT coord,
                           float compareValue) {
    return compareValue < tex.sample(samplr, coord).x ? 1.0 : 0.0;
}
template <typename TextureT, typename CoordT>
float2 textureCalculateLod(TextureT tex, sampler samplr, CoordT coord) {
    float lod = tex.calculate_unclamped_lod(samplr, coord);
    return float2(floor(lod), fract(lod));
}
int clampFI32(int v) {
    if (v == 0x7FFFFFFF)
        return as_type<int>(1.0);
    else if (v == 0xFFFFFFFF)
        return as_type<int>(0.0);
    return as_type<int>(clamp(as_type<float>(v), 0.0, 1.0));
}
float mul_nonIEEE(float a, float b) {
    if (a == 0.0 || b == 0.0)
        return 0.0;
    return a * b;
}
vertex VertexOut main0(uint vid [[vertex_id]], uint iid [[instance_id]],
                       VertexIn in [[stage_in]],
                       constant UBuff1 &ubuff1 [[buffer(0)]],
                       constant UBuff2 &ubuff2 [[buffer(1)]]) {
    VertexOut out;
    int4 R0i = int4(0);
    int4 R1i = int4(0);
    int4 R2i = int4(0);
    int4 R3i = int4(0);
    uint4 attrDecoder;
    int backupReg0i, backupReg1i, backupReg2i, backupReg3i, backupReg4i;
    int PV0ix = 0, PV0iy = 0, PV0iz = 0, PV0iw = 0, PV1ix = 0, PV1iy = 0,
        PV1iz = 0, PV1iw = 0;
    int PS0i = 0, PS1i = 0;
    int4 tempi = int4(0);
    float tempResultf;
    int tempResulti;
    int4 ARi = int4(0);
    bool predResult = true;
    R0i = int4(vid, 0, 0, iid);
    attrDecoder.xyz = in.attrDataSem0.xyz;
    attrDecoder.xyz =
        (attrDecoder.xyz >> 24) | ((attrDecoder.xyz >> 8) & 0xFF00) |
        ((attrDecoder.xyz << 8) & 0xFF0000) | ((attrDecoder.xyz << 24));
    attrDecoder.w = 0;
    R1i = int4(int(attrDecoder.x), int(attrDecoder.y), int(attrDecoder.z),
               0x3f800000);
    // 0
    R1i.x = as_type<int>(ubuff2.d[7].z);
    R0i.z = R0i.x << int(1);
    R0i.w = int(0x3f800000);
    // 1
    R0i.y = R0i.z + int(1);
    R3i.xyzw = as_type<int4>(ubuff1.d[R0i.z].xyzw);
    R2i.xyzw = as_type<int4>(ubuff1.d[R0i.y].xyzw);
    // export
    out.pointSize = (float4(as_type<float>(R1i.x), 0, 0, 0)).x * resScale;
    // 0
    R1i.x = as_type<int>(dot(
        float4(as_type<float>(R3i.x), as_type<float>(R3i.y),
               as_type<float>(R3i.z), as_type<float>(R0i.w)),
        float4(ubuff2.d[0].x, ubuff2.d[0].y, ubuff2.d[0].z, ubuff2.d[0].w)));
    PV0iy = R1i.x;
    PV0iz = R1i.x;
    PV0iw = R1i.x;
    R2i.w =
        as_type<int>(mul_nonIEEE(as_type<float>(R3i.w), as_type<float>(R2i.w)));
    // 1
    tempi.x = as_type<int>(dot(
        float4(as_type<float>(R3i.x), as_type<float>(R3i.y),
               as_type<float>(R3i.z), as_type<float>(R0i.w)),
        float4(ubuff2.d[1].x, ubuff2.d[1].y, ubuff2.d[1].z, ubuff2.d[1].w)));
    PV1ix = tempi.x;
    R1i.y = tempi.x;
    PV1iz = tempi.x;
    PV1iw = tempi.x;
    R3i.w = as_type<int>(float(R0i.x));
    // 2
    tempi.x = as_type<int>(dot(
        float4(as_type<float>(R3i.x), as_type<float>(R3i.y),
               as_type<float>(R3i.z), as_type<float>(R0i.w)),
        float4(ubuff2.d[2].x, ubuff2.d[2].y, ubuff2.d[2].z, ubuff2.d[2].w)));
    PV0ix = tempi.x;
    PV0iy = tempi.x;
    R1i.z = tempi.x;
    PV0iw = tempi.x;
    // 3
    tempi.x = as_type<int>(dot(
        float4(as_type<float>(R3i.x), as_type<float>(R3i.y),
               as_type<float>(R3i.z), as_type<float>(R0i.w)),
        float4(ubuff2.d[3].x, ubuff2.d[3].y, ubuff2.d[3].z, ubuff2.d[3].w)));
    PV1ix = tempi.x;
    PV1iy = tempi.x;
    PV1iz = tempi.x;
    R1i.w = tempi.x;
    // export
    SET_POSITION(float4(as_type<float>(R1i.x), as_type<float>(R1i.y),
                        as_type<float>(R1i.z), as_type<float>(R1i.w)));
    // export
    out.passParameterSem1 =
        float4(as_type<float>(R2i.x), as_type<float>(R2i.y),
               as_type<float>(R2i.z), as_type<float>(R2i.w));
    // export
    out.passParameterSem2 =
        float4(as_type<float>(R3i.x), as_type<float>(R3i.y),
               as_type<float>(R3i.z), as_type<float>(R3i.w));
    return out;
}
