Skip to main content

src/raylib.gleam

import ffi/ffi
import gleam/string
import raylib/inputs
import raylib/vectors

pub type Color =
  ffi.Color

pub type Image =
  ffi.Image

pub type Texture =
  ffi.Texture

pub type Rectangle =
  ffi.Rectangle

pub opaque type Monitor {
  Monitor(id: Int)
}

pub opaque type RLContext {
  RLContext
}

pub opaque type DrawingContext {
  DrawingContext
}

pub fn start(
  width width: Int,
  height height: Int,
  titled title: String,
  state state: state,
  f f: fn(RLContext, state) -> state,
) -> Nil {
  ffi.init_window(width, height, title)
  loop(RLContext, state, f)
  ffi.close_window()
}

fn loop(
  rc: RLContext,
  state: state,
  f: fn(RLContext, state) -> state,
) -> state {
  case ffi.window_should_close() {
    True -> state
    False -> {
      let state = f(rc, state)
      loop(rc, state, f)
    }
  }
}

pub fn draw(_: RLContext, actions actions: fn(DrawingContext) -> t) -> t {
  ffi.begin_drawing()
  let result = actions(DrawingContext)
  ffi.end_drawing()
  result
}

// re-exports
pub fn clear_background(_: DrawingContext, color color: Color) -> Nil {
  ffi.clear_background(color)
}

pub fn disable_cursor(_: RLContext) -> Nil {
  ffi.disable_cursor()
}

pub fn disable_event_waiting(_: RLContext) -> Nil {
  ffi.disable_event_waiting()
}

pub fn draw_circle(
  _: DrawingContext,
  x x: Int,
  y y: Int,
  radius radius: Float,
  color color: Color,
) -> Nil {
  ffi.draw_circle(x, y, radius, color)
}

pub fn draw_circle_lines(
  _: DrawingContext,
  x x: Int,
  y y: Int,
  radius radius: Float,
  color color: Color,
) -> Nil {
  ffi.draw_circle_lines(x, y, radius, color)
}

pub fn draw_circle_sector(
  _: DrawingContext,
  center center: vectors.Vec2,
  radius radius: Float,
  from start_angle: Float,
  to end_angle: Float,
  segments segments: Int,
  color color: Color,
) -> Nil {
  ffi.draw_circle_sector(
    vectors.vector2(center),
    radius,
    start_angle,
    end_angle,
    segments,
    color,
  )
}

pub fn draw_circle_sector_lines(
  _: DrawingContext,
  center center: vectors.Vec2,
  radius radius: Float,
  from start_angle: Float,
  to end_angle: Float,
  segments segments: Int,
  color color: Color,
) -> Nil {
  ffi.draw_circle_sector_lines(
    vectors.vector2(center),
    radius,
    start_angle,
    end_angle,
    segments,
    color,
  )
}

pub fn draw_ellipse(
  _: DrawingContext,
  x x: Int,
  y y: Int,
  radius_h radius_h: Float,
  radius_v radius_v: Float,
  color color: Color,
) -> Nil {
  ffi.draw_ellipse(x, y, radius_h, radius_v, color)
}

pub fn draw_ellipse_lines(
  _: DrawingContext,
  x x: Int,
  y y: Int,
  radius_h radius_h: Float,
  radius_v radius_v: Float,
  color color: Color,
) -> Nil {
  ffi.draw_ellipse_lines(x, y, radius_h, radius_v, color)
}

pub fn draw_line(
  _: DrawingContext,
  sx sx: Int,
  sy sy: Int,
  ex ex: Int,
  ey ey: Int,
  color color: Color,
) -> Nil {
  ffi.draw_line(sx, sy, ex, ey, color)
}

pub fn draw_line_bezier(
  _: DrawingContext,
  start start: vectors.Vec2,
  end end: vectors.Vec2,
  thick thick: Float,
  color color: Color,
) -> Nil {
  ffi.draw_line_bezier(
    vectors.vector2(start),
    vectors.vector2(end),
    thick,
    color,
  )
}

pub fn draw_line_ex(
  _: DrawingContext,
  start start: vectors.Vec2,
  end end: vectors.Vec2,
  thick thick: Float,
  color color: Color,
) -> Nil {
  ffi.draw_line_ex(vectors.vector2(start), vectors.vector2(end), thick, color)
}

pub fn draw_pixel(
  _: DrawingContext,
  x x: Int,
  y y: Int,
  color color: Color,
) -> Nil {
  ffi.draw_pixel(x, y, color)
}

pub fn draw_rectangle(
  _: DrawingContext,
  x x: Int,
  y y: Int,
  w width: Int,
  h height: Int,
  color color: Color,
) -> Nil {
  ffi.draw_rectangle(x, y, width, height, color)
}

pub fn draw_rectangle_pro(
  _: DrawingContext,
  rec rec: Rectangle,
  origin origin: vectors.Vec2,
  rot rotation: Float,
  color color: Color,
) -> Nil {
  ffi.draw_rectangle_pro(rec, vectors.vector2(origin), rotation, color)
}

pub fn draw_rectangle_rounded(
  _: DrawingContext,
  rec rec: Rectangle,
  roundness roundness: Float,
  segments segments: Int,
  color color: Color,
) -> Nil {
  ffi.draw_rectangle_rounded(rec, roundness, segments, color)
}

pub fn draw_rectangle_rounded_lines_ex(
  _: DrawingContext,
  rec rec: Rectangle,
  roundness roundness: Float,
  segments segments: Int,
  thick thick: Float,
  color color: Color,
) -> Nil {
  ffi.draw_rectangle_rounded_lines_ex(rec, roundness, segments, thick, color)
}

pub fn draw_ring(
  _: DrawingContext,
  center: vectors.Vec2,
  from_radius inner_radius: Float,
  to_radius outer_radius: Float,
  from_angle start_angle: Float,
  to_angle end_angle: Float,
  segments segments: Int,
  color color: Color,
) -> Nil {
  ffi.draw_ring(
    vectors.vector2(center),
    inner_radius,
    outer_radius,
    start_angle,
    end_angle,
    segments,
    color,
  )
}

pub fn draw_ring_lines(
  _: DrawingContext,
  center center: vectors.Vec2,
  from_radius inner_radius: Float,
  to_radius outer_radius: Float,
  from_angle start_angle: Float,
  to_angle end_angle: Float,
  segments segments: Float,
  color color: Color,
) -> Nil {
  ffi.draw_ring_lines(
    vectors.vector2(center),
    inner_radius,
    outer_radius,
    start_angle,
    end_angle,
    segments,
    color,
  )
}

pub fn enable_cursor(_: RLContext) -> Nil {
  ffi.enable_cursor()
}

pub fn enable_event_waiting(_: RLContext) -> Nil {
  ffi.enable_event_waiting()
}

pub fn get_char_pressed(_: RLContext) -> Result(UtfCodepoint, Nil) {
  string.utf_codepoint(ffi.get_char_pressed())
}

pub fn get_clipboard_image(_: RLContext) -> Image {
  ffi.get_clipboard_image()
}

pub fn get_clipboard_text(_: RLContext) -> String {
  ffi.get_clipboard_text()
}

pub fn get_color(from hex: Int) -> Color {
  ffi.get_color(hex)
}

pub fn get_fps(_: RLContext) -> Int {
  ffi.get_fps()
}

pub fn get_frame_time(_: RLContext) -> Float {
  ffi.get_frame_time()
}

pub fn get_key_pressed(_: RLContext) -> inputs.KeyCode {
  inputs.KeyCode(ffi.get_key_pressed())
}

pub fn get_monitor_count(_: RLContext) -> Int {
  ffi.get_monitor_count()
}

pub fn get_current_monitor(_: RLContext) -> Monitor {
  Monitor(ffi.get_current_monitor())
}

pub fn get_monitor_height(_: RLContext, of monitor: Monitor) -> Int {
  ffi.get_monitor_height(monitor.id)
}

pub fn get_monitor_name(_: RLContext, of monitor: Monitor) -> String {
  ffi.get_monitor_name(monitor.id)
}

pub fn get_monitor_physical_height(_: RLContext, of monitor: Monitor) -> Int {
  ffi.get_monitor_physical_height(monitor.id)
}

pub fn get_monitor_physical_width(_: RLContext, of monitor: Monitor) -> Int {
  ffi.get_monitor_physical_width(monitor.id)
}

pub fn get_monitor_position(_: RLContext, of monitor: Monitor) -> vectors.Vec2 {
  vectors.vec2(ffi.get_monitor_position(monitor.id))
}

pub fn get_monitor_refresh_rate(_: RLContext, of monitor: Monitor) -> Int {
  ffi.get_monitor_refresh_rate(monitor.id)
}

pub fn get_monitor_width(_: RLContext, of monitor: Monitor) -> Int {
  ffi.get_monitor_width(monitor.id)
}

pub fn get_mouse_delta(_: RLContext) -> vectors.Vec2 {
  vectors.vec2(ffi.get_mouse_delta())
}

pub fn get_mouse_position(_: RLContext) -> vectors.Vec2 {
  vectors.vec2(ffi.get_mouse_position())
}

pub fn get_mouse_wheel_move(_: RLContext) -> Float {
  ffi.get_mouse_wheel_move()
}

pub fn get_mouse_wheel_move_v(_: RLContext) -> vectors.Vec2 {
  vectors.vec2(ffi.get_mouse_wheel_move_v())
}

pub fn get_mouse_x(_: RLContext) -> Int {
  ffi.get_mouse_x()
}

pub fn get_mouse_y(_: RLContext) -> Int {
  ffi.get_mouse_y()
}

pub fn get_render_height(_: RLContext) -> Int {
  ffi.get_render_height()
}

pub fn get_render_width(_: RLContext) -> Int {
  ffi.get_render_width()
}

pub fn get_screen_height(_: RLContext) -> Int {
  ffi.get_screen_height()
}

pub fn get_shapes_texture(_: RLContext) -> Texture {
  ffi.get_shapes_texture()
}

pub fn get_shapes_texture_rectangle(_: RLContext) -> Rectangle {
  ffi.get_shapes_texture_rectangle()
}

pub fn get_time(_: RLContext) -> Float {
  ffi.get_time()
}

pub fn get_window_position(_: RLContext) -> vectors.Vec2 {
  vectors.vec2(ffi.get_window_position())
}

pub fn get_window_scale_dpi(_: RLContext) -> vectors.Vec2 {
  vectors.vec2(ffi.get_window_scale_dpi())
}

pub fn hide_cursor(_: RLContext) -> Nil {
  ffi.hide_cursor()
}

pub fn get_screen_width(_: RLContext) -> Int {
  ffi.get_screen_width()
}

pub fn is_cursor_hidden(_: RLContext) -> Bool {
  ffi.is_cursor_hidden()
}

pub fn is_cursor_on_screen(_: RLContext) -> Bool {
  ffi.is_cursor_on_screen()
}

pub fn is_key_down(_: RLContext, code code: inputs.KeyCode) -> Bool {
  ffi.is_key_down(code.code)
}

pub fn is_key_pressed(_: RLContext, code code: inputs.KeyCode) -> Bool {
  ffi.is_key_pressed(code.code)
}

pub fn is_key_pressed_repeat(_: RLContext, code code: inputs.KeyCode) -> Bool {
  ffi.is_key_pressed_repeat(code.code)
}

pub fn is_key_released(_: RLContext, code code: inputs.KeyCode) -> Bool {
  ffi.is_key_released(code.code)
}

pub fn is_key_up(_: RLContext, code code: inputs.KeyCode) -> Bool {
  ffi.is_key_up(code.code)
}

pub fn is_mouse_button_down(
  _: RLContext,
  code code: inputs.MouseButtonCode,
) -> Bool {
  ffi.is_mouse_button_down(code.code)
}

pub fn is_mouse_button_pressed(
  _: RLContext,
  code code: inputs.MouseButtonCode,
) -> Bool {
  ffi.is_mouse_button_pressed(code.code)
}

pub fn is_mouse_button_released(
  _: RLContext,
  code code: inputs.MouseButtonCode,
) -> Bool {
  ffi.is_mouse_button_released(code.code)
}

pub fn is_mouse_button_up(
  _: RLContext,
  code code: inputs.MouseButtonCode,
) -> Bool {
  ffi.is_mouse_button_up(code.code)
}

pub fn is_window_focused(_: RLContext) -> Bool {
  ffi.is_window_focused()
}

pub fn is_window_fullscreen(_: RLContext) -> Bool {
  ffi.is_window_fullscreen()
}

pub fn is_window_hidden(_: RLContext) -> Bool {
  ffi.is_window_hidden()
}

pub fn is_window_maximized(_: RLContext) -> Bool {
  ffi.is_window_maximized()
}

pub fn is_window_minimized(_: RLContext) -> Bool {
  ffi.is_window_minimized()
}

pub fn is_window_resized(_: RLContext) -> Bool {
  ffi.is_window_resized()
}

pub fn maximize_window(_: RLContext) -> Nil {
  ffi.maximize_window()
}

pub fn minimize_window(_: RLContext) -> Nil {
  ffi.minimize_window()
}

pub fn restore_window(_: RLContext) -> Nil {
  ffi.restore_window()
}

pub fn set_clipboard_text(_: RLContext, to text: String) -> Nil {
  ffi.set_clipboard_text(text)
}

pub fn set_exit_key(_: RLContext, code code: inputs.KeyCode) -> Nil {
  ffi.set_exit_key(code.code)
}

pub fn set_mouse_position(_: RLContext, x x: Int, y y: Int) -> Nil {
  ffi.set_mouse_position(x, y)
}

pub fn set_mouse_scale(_: RLContext, x x: Float, y y: Float) -> Nil {
  ffi.set_mouse_scale(x, y)
}

pub fn set_shapes_texture(
  _: RLContext,
  to texture: Texture,
  source source: Rectangle,
) -> Nil {
  ffi.set_shapes_texture(texture, source)
}

pub fn set_target_fps(_: RLContext, to fps: Int) -> Nil {
  ffi.set_target_fps(fps)
}

pub fn set_window_focused(_: RLContext) -> Nil {
  ffi.set_window_focused()
}

pub fn set_window_icon(_: RLContext, to image: Image) -> Nil {
  ffi.set_window_icon(image)
}

pub fn set_window_max_size(
  _: RLContext,
  width width: Int,
  height height: Int,
) -> Nil {
  ffi.set_window_max_size(width, height)
}

pub fn set_window_min_size(
  _: RLContext,
  width width: Int,
  height height: Int,
) -> Nil {
  ffi.set_window_min_size(width, height)
}

pub fn set_window_monitor(_: RLContext, to monitor: Int) -> Nil {
  ffi.set_window_monitor(monitor)
}

pub fn set_window_opacity(_: RLContext, to opacity: Float) -> Nil {
  ffi.set_window_opacity(opacity)
}

pub fn set_window_position(_: RLContext, x x: Int, y y: Int) -> Nil {
  ffi.set_window_position(x, y)
}

pub fn set_window_size(
  _: RLContext,
  width width: Int,
  height height: Int,
) -> Nil {
  ffi.set_window_size(width, height)
}

pub fn set_window_title(_: RLContext, to title: String) -> Nil {
  ffi.set_window_title(title)
}

pub fn show_cursor(_: RLContext) -> Nil {
  ffi.show_cursor()
}

pub fn take_screenshot(_: RLContext, to file: String) -> Nil {
  ffi.take_screenshot(file)
}

pub fn toggle_borderless_windowed(_: RLContext) -> Nil {
  ffi.toggle_borderless_windowed()
}

pub fn toggle_fullscreen(_: RLContext) -> Nil {
  ffi.toggle_fullscreen()
}