#[macro_use]
mod macros;
pub mod audio;
pub mod automation;
pub mod callbacks;
pub mod camera;
pub mod collision;
pub mod color;
pub mod data;
pub mod drawing;
pub mod error;
pub mod file;
pub mod input;
pub mod logging;
pub mod math;
pub mod misc;
pub mod models;
pub mod shaders;
pub mod text;
pub mod texture;
pub mod vr;
pub mod window;
use raylib_sys::TraceLogLevel;
use crate::ffi;
use std::ffi::CString;
use std::marker::PhantomData;
#[macro_export]
macro_rules! rstr {
($e:tt) => ({
#[allow(unused_unsafe)]
unsafe {
std::ffi::CStr::from_bytes_with_nul_unchecked(concat!($e, "\0").as_bytes())
}
});
($e:tt, $($arg:tt)*) => ({
#[allow(unused_unsafe)]
unsafe {
std::ffi::CString::new(format!($e, $($arg)*)).unwrap()
}
})
}
#[derive(Clone, Debug)]
pub struct RaylibThread(PhantomData<*const ()>);
#[derive(Debug)]
pub struct RaylibHandle(());
impl Drop for RaylibHandle {
fn drop(&mut self) {
unsafe {
if ffi::IsWindowReady() {
ffi::CloseWindow();
}
}
}
}
#[derive(Debug, Default)]
pub struct RaylibBuilder {
fullscreen_mode: bool,
window_resizable: bool,
window_undecorated: bool,
window_transparent: bool,
msaa_4x_hint: bool,
vsync_hint: bool,
log_level: TraceLogLevel,
width: i32,
height: i32,
title: String,
#[cfg(feature = "imgui")]
imgui_theme: crate::imgui::ImGuiTheme,
}
pub fn init() -> RaylibBuilder {
RaylibBuilder {
width: 640,
height: 480,
title: "raylib-rs".to_string(),
..Default::default()
}
}
impl RaylibBuilder {
pub fn fullscreen(&mut self) -> &mut Self {
self.fullscreen_mode = true;
self
}
pub fn log_level(&mut self, level: TraceLogLevel) -> &mut Self {
self.log_level = level;
self
}
pub fn resizable(&mut self) -> &mut Self {
self.window_resizable = true;
self
}
pub fn undecorated(&mut self) -> &mut Self {
self.window_undecorated = true;
self
}
pub fn transparent(&mut self) -> &mut Self {
self.window_transparent = true;
self
}
pub fn msaa_4x(&mut self) -> &mut Self {
self.msaa_4x_hint = true;
self
}
pub fn vsync(&mut self) -> &mut Self {
self.vsync_hint = true;
self
}
pub fn width(&mut self, w: i32) -> &mut Self {
self.width = w;
self
}
pub fn height(&mut self, h: i32) -> &mut Self {
self.height = h;
self
}
pub fn size(&mut self, w: i32, h: i32) -> &mut Self {
self.width = w;
self.height = h;
self
}
pub fn title(&mut self, text: &str) -> &mut Self {
self.title = text.to_string();
self
}
#[cfg(feature = "imgui")]
pub fn imgui_theme(&mut self, theme: crate::imgui::ImGuiTheme) -> &mut Self {
self.imgui_theme = theme;
self
}
pub fn build(&self) -> (RaylibHandle, RaylibThread) {
use crate::consts::ConfigFlags::*;
let mut flags = 0u32;
if self.fullscreen_mode {
flags |= FLAG_FULLSCREEN_MODE as u32;
}
if self.window_resizable {
flags |= FLAG_WINDOW_RESIZABLE as u32;
}
if self.window_undecorated {
flags |= FLAG_WINDOW_UNDECORATED as u32;
}
if self.window_transparent {
flags |= FLAG_WINDOW_TRANSPARENT as u32;
}
if self.msaa_4x_hint {
flags |= FLAG_MSAA_4X_HINT as u32;
}
if self.vsync_hint {
flags |= FLAG_VSYNC_HINT as u32;
}
unsafe {
ffi::SetConfigFlags(flags as u32);
}
unsafe {
ffi::SetTraceLogLevel(self.log_level as i32);
}
let rl = init_window(self.width, self.height, &self.title);
#[cfg(feature = "imgui")]
unsafe {
crate::imgui::init_imgui_context(self.imgui_theme == crate::imgui::ImGuiTheme::Dark);
}
(rl, RaylibThread(PhantomData))
}
}
fn init_window(width: i32, height: i32, title: &str) -> RaylibHandle {
if unsafe { ffi::IsWindowReady() } {
panic!("Attempted to initialize raylib-rs more than once!");
} else {
unsafe {
let c_title = CString::new(title).unwrap();
ffi::InitWindow(width, height, c_title.as_ptr());
}
if !unsafe { ffi::IsWindowReady() } {
panic!("Attempting to create window failed!");
}
RaylibHandle(())
}
}