#include <metal_stdlib>
#include <simd/simd.h>

using namespace metal;

struct Uniforms
{
    float4x4 projection;
    float dpi_scale;
    uint mode;
};

struct Core_2D_Primitive
{
    float4 bounds;
    uint color;
    uint flags;
    uint rotation_sc;
    float _pad;
    float4 params;
    float4 params2;
    float4 uv_rect;
    uint4 effects;
};

struct Core_2D_Primitive_1
{
    float4 bounds;
    uint color;
    uint flags;
    uint rotation_sc;
    float _pad;
    float4 params;
    float4 params2;
    float4 uv_rect;
    uint4 effects;
};

struct Core_2D_Primitives
{
    Core_2D_Primitive_1 primitives[1];
};

struct main0_out
{
    float4 f_color [[user(locn0)]];
    float2 f_local_or_uv [[user(locn1)]];
    float4 f_params [[user(locn2)]];
    float4 f_params2 [[user(locn3)]];
    uint f_flags [[user(locn4)]];
    float4 f_uv_rect [[user(locn6)]];
    uint4 f_effects [[user(locn7)]];
    float4 gl_Position [[position]];
};

struct main0_in
{
    float2 v_position [[attribute(0)]];
    float2 v_uv [[attribute(1)]];
    float4 v_color [[attribute(2)]];
};

vertex main0_out main0(main0_in in [[stage_in]], constant Uniforms& _12 [[buffer(0)]], const device Core_2D_Primitives& _31 [[buffer(1)]], uint gl_InstanceIndex [[instance_id]])
{
    main0_out out = {};
    if (_12.mode == 1u)
    {
        Core_2D_Primitive p;
        p.bounds = _31.primitives[int(gl_InstanceIndex)].bounds;
        p.color = _31.primitives[int(gl_InstanceIndex)].color;
        p.flags = _31.primitives[int(gl_InstanceIndex)].flags;
        p.rotation_sc = _31.primitives[int(gl_InstanceIndex)].rotation_sc;
        p._pad = _31.primitives[int(gl_InstanceIndex)]._pad;
        p.params = _31.primitives[int(gl_InstanceIndex)].params;
        p.params2 = _31.primitives[int(gl_InstanceIndex)].params2;
        p.uv_rect = _31.primitives[int(gl_InstanceIndex)].uv_rect;
        p.effects = _31.primitives[int(gl_InstanceIndex)].effects;
        float2 corner = in.v_position;
        float2 world_pos = mix(p.bounds.xy, p.bounds.zw, corner);
        float2 center = (p.bounds.xy + p.bounds.zw) * 0.5;
        float2 local = (world_pos - center) * _12.dpi_scale;
        uint flags = (p.flags >> 8u) & 255u;
        if ((flags & 16u) != 0u)
        {
            float2 sc = float2(as_type<half2>(p.rotation_sc));
            local = float2((sc.y * local.x) + (sc.x * local.y), ((-sc.x) * local.x) + (sc.y * local.y));
        }
        out.f_color = unpack_unorm4x8_to_float(p.color);
        out.f_local_or_uv = local;
        out.f_params = p.params;
        out.f_params2 = p.params2;
        out.f_flags = p.flags;
        out.f_uv_rect = p.uv_rect;
        out.f_effects = p.effects;
        out.gl_Position = _12.projection * float4(world_pos * _12.dpi_scale, 0.0, 1.0);
    }
    else
    {
        out.f_color = in.v_color;
        out.f_local_or_uv = in.v_uv;
        out.f_params = float4(0.0);
        out.f_params2 = float4(0.0);
        out.f_flags = 0u;
        out.f_uv_rect = float4(0.0);
        out.f_effects = uint4(0u);
        float2 _199;
        if (_12.mode == 2u)
        {
            _199 = in.v_position;
        }
        else
        {
            _199 = in.v_position * _12.dpi_scale;
        }
        float2 pos = _199;
        out.gl_Position = _12.projection * float4(pos, 0.0, 1.0);
    }
    return out;
}

