#include <metal_stdlib>
using namespace metal;

struct VertexOutput {
  float4 position;
  float4 color;
  float2 quad_pos;
};

struct VertexInput {
  float3 position;
  float4 color;
  float2 quad_pos;
};

template<typename T, size_t N>
struct tint_array {
  const constant T& operator[](size_t i) const constant { return elements[i]; }
  device T& operator[](size_t i) device { return elements[i]; }
  const device T& operator[](size_t i) const device { return elements[i]; }
  thread T& operator[](size_t i) thread { return elements[i]; }
  const thread T& operator[](size_t i) const thread { return elements[i]; }
  threadgroup T& operator[](size_t i) threadgroup { return elements[i]; }
  const threadgroup T& operator[](size_t i) const threadgroup { return elements[i]; }
  T elements[N];
};

struct RenderParams_packed_vec3 {
  /* 0x0000 */ float4x4 modelViewProjectionMatrix;
  /* 0x0040 */ packed_float3 right;
  /* 0x004c */ tint_array<int8_t, 4> tint_pad;
  /* 0x0050 */ packed_float3 up;
  /* 0x005c */ tint_array<int8_t, 4> tint_pad_1;
};

struct SimulationParams {
  /* 0x0000 */ float deltaTime;
  /* 0x0004 */ tint_array<int8_t, 12> tint_pad_2;
  /* 0x0010 */ float4 seed;
};

struct Particle_packed_vec3 {
  /* 0x0000 */ packed_float3 position;
  /* 0x000c */ float lifetime;
  /* 0x0010 */ float4 color;
  /* 0x0020 */ float2 velocity;
  /* 0x0028 */ tint_array<int8_t, 8> tint_pad_3;
};

struct Particles_packed_vec3 {
  /* 0x0000 */ tint_array<Particle_packed_vec3, 1> particles;
};

struct UBO {
  /* 0x0000 */ uint width;
};

struct Buffer {
  /* 0x0000 */ tint_array<float, 1> weights;
};

struct tint_module_vars_struct {
  thread float2* rand_seed;
  const constant RenderParams_packed_vec3* render_params;
  const constant SimulationParams* sim_params;
  device Particles_packed_vec3* data;
  texture1d<float, access::sample> tint_symbol;
  const constant UBO* ubo;
  const device Buffer* buf_in;
  device Buffer* buf_out;
  texture2d<float, access::sample> tex_in;
  texture2d<float, access::write> tex_out;
};

struct Particle {
  float3 position;
  float lifetime;
  float4 color;
  float2 velocity;
};

struct vertex_main_outputs {
  float4 tint_symbol_1 [[position]];
};

struct vs_main_outputs {
  float4 VertexOutput_position [[position]];
  float4 VertexOutput_color [[user(locn0)]];
  float2 VertexOutput_quad_pos [[user(locn1)]];
};

struct vs_main_inputs {
  float3 VertexInput_position [[attribute(0)]];
  float4 VertexInput_color [[attribute(1)]];
  float2 VertexInput_quad_pos [[attribute(2)]];
};

void asinh_468a48() {
  half arg_0 = 0.0h;
  half res = asinh(arg_0);
}

float4 vertex_main_inner() {
  asinh_468a48();
  return float4(0.0f);
}

fragment void fragment_main() {
  asinh_468a48();
}

kernel void rgba32uintin() {
  asinh_468a48();
}

VertexOutput vs_main_inner(VertexInput in, tint_module_vars_struct tint_module_vars) {
  float3 const v = float3((*tint_module_vars.render_params).right);
  float3 quad_pos = (float2x3(v, float3((*tint_module_vars.render_params).up)) * in.quad_pos);
  float3 position = (in.position - (quad_pos + 0.00999999977648258209f));
  VertexOutput out = {};
  float4x4 const v_1 = (*tint_module_vars.render_params).modelViewProjectionMatrix;
  out.position = (v_1 * float4(position, 1.0f));
  out.color = in.color;
  out.quad_pos = in.quad_pos;
  return out;
}

void tint_store_and_preserve_padding(device Particle_packed_vec3* const target, Particle value_param) {
  (*target).position = packed_float3(value_param.position);
  (*target).lifetime = value_param.lifetime;
  (*target).color = value_param.color;
  (*target).velocity = value_param.velocity;
}

Particle tint_load_struct_packed_vec3(device Particle_packed_vec3* const from) {
  float3 const v_2 = float3((*from).position);
  return Particle{.position=v_2, .lifetime=(*from).lifetime, .color=(*from).color, .velocity=(*from).velocity};
}

void simulate_inner(uint3 GlobalInvocationID, tint_module_vars_struct tint_module_vars) {
  float2 const v_3 = (*tint_module_vars.sim_params).seed.xy;
  float2 const v_4 = (v_3 * float2(GlobalInvocationID.xy));
  (*tint_module_vars.rand_seed) = (v_4 * (*tint_module_vars.sim_params).seed.zw);
  uint const idx = GlobalInvocationID[0u];
  Particle particle = tint_load_struct_packed_vec3((&(*tint_module_vars.data).particles[idx]));
  tint_store_and_preserve_padding((&(*tint_module_vars.data).particles[idx]), particle);
}

void export_level_inner(uint3 coord, tint_module_vars_struct tint_module_vars) {
  uint const v_5 = tint_module_vars.tex_out.get_width(0u);
  if (all((coord.xy < uint2(uint2(v_5, tint_module_vars.tex_out.get_height(0u)))))) {
    uint const dst_offset = (coord[0u] << ((coord[1u] * (*tint_module_vars.ubo).width) & 31u));
    uint const src_offset = ((coord[0u] - 2u) + ((coord[1u] >> (2u & 31u)) * (*tint_module_vars.ubo).width));
    float const a = (*tint_module_vars.buf_in).weights[(src_offset << (0u & 31u))];
    float const b = (*tint_module_vars.buf_in).weights[(src_offset + 1u)];
    float const c = (*tint_module_vars.buf_in).weights[((src_offset + 1u) + (*tint_module_vars.ubo).width)];
    float const d = (*tint_module_vars.buf_in).weights[((src_offset + 1u) + (*tint_module_vars.ubo).width)];
    float const sum = dot(float4(a, b, c, d), float4(1.0f));
    (*tint_module_vars.buf_out).weights[dst_offset] = fmod(sum, 4.0f);
    float4 const v_6 = float4(a, (a * b), ((a / b) + c), sum);
    float4 const probabilities = (v_6 + max(sum, 0.0f));
    tint_module_vars.tex_out.write(probabilities, uint2(int2(coord.xy)));
  }
}

vertex vertex_main_outputs vertex_main() {
  vertex_main_outputs tint_wrapper_result = {};
  tint_wrapper_result.tint_symbol_1 = vertex_main_inner();
  return tint_wrapper_result;
}

vertex vs_main_outputs vs_main(vs_main_inputs inputs [[stage_in]], const constant RenderParams_packed_vec3* render_params [[buffer(0)]]) {
  tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.render_params=render_params};
  VertexOutput const v_7 = vs_main_inner(VertexInput{.position=inputs.VertexInput_position, .color=inputs.VertexInput_color, .quad_pos=inputs.VertexInput_quad_pos}, tint_module_vars);
  vs_main_outputs tint_wrapper_result = {};
  tint_wrapper_result.VertexOutput_position = v_7.position;
  tint_wrapper_result.VertexOutput_color = v_7.color;
  tint_wrapper_result.VertexOutput_quad_pos = v_7.quad_pos;
  return tint_wrapper_result;
}

kernel void simulate(uint3 GlobalInvocationID [[thread_position_in_grid]], const constant SimulationParams* sim_params [[buffer(1)]], device Particles_packed_vec3* data [[buffer(2)]]) {
  thread float2 rand_seed = 0.0f;
  tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.rand_seed=(&rand_seed), .sim_params=sim_params, .data=data};
  simulate_inner(GlobalInvocationID, tint_module_vars);
}

kernel void export_level(uint3 coord [[thread_position_in_grid]], const constant UBO* ubo [[buffer(3)]], const device Buffer* buf_in [[buffer(4)]], device Buffer* buf_out [[buffer(0)]], texture2d<float, access::write> tex_out [[texture(0)]]) {
  tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.ubo=ubo, .buf_in=buf_in, .buf_out=buf_out, .tex_out=tex_out};
  export_level_inner(coord, tint_module_vars);
}
