fermium 22605.0.0

An opinionated crate of SDL2 bindings.
Documentation
#![allow(clippy::uninlined_format_args)]

use fermium::prelude::*;

fn print_error() {
  unsafe {
    let mut v = Vec::with_capacity(4096);
    let p = SDL_GetErrorMsg(v.as_mut_ptr(), v.capacity() as _).cast();
    print_ptr(p);
  }
}

unsafe fn print_ptr(mut p: *const u8) {
  while *p != 0 {
    print!("{}", *p as char);
    p = p.add(1);
  }
}

/// # Safety
/// get out of my face clippy
pub unsafe fn set_controller_use_button_labels(labels: bool) -> bool {
  const SDL_HINT_GAMECONTROLLER_USE_BUTTON_LABELS: &[u8] =
    b"SDL_GAMECONTROLLER_USE_BUTTON_LABELS\0";
  let value: &[u8] = if labels { b"1\0" } else { b"0\0" };
  unsafe {
    SDL_SetHint(
      SDL_HINT_GAMECONTROLLER_USE_BUTTON_LABELS.as_ptr().cast(),
      value.as_ptr().cast(),
    )
  }
  .into()
}

fn main() {
  unsafe {
    assert_eq!(SDL_Init(SDL_INIT_EVERYTHING), 0);
    set_controller_use_button_labels(true);

    let win = SDL_CreateWindow(
      b"demo\0".as_ptr().cast(),
      SDL_WINDOWPOS_CENTERED,
      SDL_WINDOWPOS_CENTERED,
      800,
      600,
      (SDL_WINDOW_OPENGL | SDL_WINDOW_ALLOW_HIGHDPI).0,
    );
    assert!(!win.is_null());

    let num_joysticks = SDL_NumJoysticks();
    println!("SDL2 reports num_joysticks: {}", num_joysticks);

    let mut event = SDL_Event::default();
    loop {
      assert_eq!(SDL_WaitEvent(&mut event), 1);
      match event.type_ {
        SDL_QUIT => {
          println!("SDL_QUIT");
          break;
        }
        SDL_KEYDOWN => {
          println!("SDL_KEYDOWN: {:?}", event.key);
        }
        SDL_KEYUP => {
          println!("SDL_KEYUP {:?}", event.key);
        }
        SDL_CONTROLLERAXISMOTION => {
          println!("SDL_CONTROLLERAXISMOTION: {:?}", event.caxis);
        }
        SDL_CONTROLLERBUTTONDOWN => {
          println!("SDL_CONTROLLERBUTTONDOWN: {:?}", event.cbutton);
        }
        SDL_CONTROLLERBUTTONUP => {
          println!("SDL_CONTROLLERBUTTONUP: {:?}", event.cbutton);
        }
        SDL_CONTROLLERDEVICEADDED => {
          println!("SDL_CONTROLLERDEVICEADDED: {:?}", event.cdevice);
          let id = event.cdevice.which;
          println!("Opening joystick {} as a controller...", id);
          let controller = SDL_GameControllerOpen(id);
          if controller.is_null() {
            print!("Error while opening: ");
            print_error();
            println!();
          } else {
            print!("> Name: ");
            let name_p = SDL_GameControllerName(controller).cast();
            print_ptr(name_p);
            println!();
            //
            println!("> Type: {:?}", SDL_GameControllerGetType(controller));
            println!(
              "> PlayerIndex: {:?}",
              SDL_GameControllerGetPlayerIndex(controller)
            );
            println!(
              "> Vendor: {:#X?}",
              SDL_GameControllerGetVendor(controller)
            );
            println!(
              "> Product: {:#X?}",
              SDL_GameControllerGetProduct(controller)
            );
            println!(
              "> ProductVersion: {:?}",
              SDL_GameControllerGetProductVersion(controller)
            );
            //
            print!("> Serial: ");
            let serial_p: *const u8 =
              SDL_GameControllerGetSerial(controller).cast();
            if serial_p.is_null() {
              println!("not available");
            } else {
              print_ptr(serial_p);
              println!();
            }
            print!("> Mapping: ");
            let mapping_p: *const u8 =
              SDL_GameControllerMapping(controller).cast();
            if mapping_p.is_null() {
              println!("not available");
            } else {
              print_ptr(mapping_p);
              SDL_free(mapping_p as _);
              println!();
            }
          }
        }
        SDL_CONTROLLERDEVICEREMOVED => {
          println!("SDL_CONTROLLERDEVICEREMOVED: {:?}", event.cdevice);
          let id = event.cdevice.which;
          println!("Closing ID {}...", id);
          let controller = SDL_GameControllerFromInstanceID(SDL_JoystickID(id));
          if controller.is_null() {
            println!("but it was already closed!");
          } else {
            SDL_GameControllerClose(controller);
          }
        }
        SDL_CONTROLLERDEVICEREMAPPED => {
          println!("SDL_CONTROLLERDEVICEREMAPPED: {:?}", event.cdevice);
        }
        SDL_CONTROLLERTOUCHPADDOWN => {
          println!("SDL_CONTROLLERTOUCHPADDOWN: {:?}", event.ctouchpad);
        }
        SDL_CONTROLLERTOUCHPADMOTION => {
          println!("SDL_CONTROLLERTOUCHPADMOTION: {:?}", event.ctouchpad);
        }
        SDL_CONTROLLERTOUCHPADUP => {
          println!("SDL_CONTROLLERTOUCHPADUP: {:?}", event.ctouchpad);
        }
        SDL_CONTROLLERSENSORUPDATE => {
          println!("SDL_CONTROLLERSENSORUPDATE: {:?}", event.ctouchpad);
        }
        _ => (),
      }
    }

    SDL_Quit();
  }
}