Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@
[core] REVIEWED: HighDPI support on macOS retina (#1510)
[core] REDESIGNED: GetFileExtension(), includes the .dot
[core] REDESIGNED: IsFileExtension(), includes the .dot
[core] REDESIGNED: Compresion API to use sdefl/sinfl libs
[core] REDESIGNED: Compression API to use sdefl/sinfl libs
- [rlgl] ADDED: SUPPORT_GL_DETAILS_INFO config flag
[rlgl] REMOVED: GenTexture\*() functions (#721)
[rlgl] REVIEWED: rlLoadShaderDefault()
Expand Down Expand Up @@ -118,7 +118,7 @@ Added: Vector2Reflect
Added: Vector2LengthSqr
Added: Vector2MoveTowards
Added: UnloadFontData
Added: LoadFontFromMemmory(ttf)
Added: LoadFontFromMemory(ttf)
Added: ColorAlphaBlend
Added: GetPixelColor
Added: SetPixelColor
Expand Down
2 changes: 1 addition & 1 deletion DECISIONS.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
Document where I put all the little design decisions that go into this library.

1. Allocations
A few functiosn in raylib return a buffer that should be deallocated by the user. Previously, we copied this data into a Vector and then freed with libc::free.
A few functions in raylib return a buffer that should be deallocated by the user. Previously, we copied this data into a Vector and then freed with libc::free.

If the user had a custom alocator or some other strange linking strategy, this would free an invalid pointer.

Expand Down
5 changes: 3 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ Though this binding tries to stay close to the simple C API, it makes some chang

Most development happens over at: https://github.com/raylib-rs/raylib-rs

Versions normally match Raylib's own, with the minor number incremented for any patches (i.e. 5.5.1 for Raylib v5.5). On occassion, if enough breaking changes are made in between Raylib releases, we'll release a 5.6, which is 5.5 but with breaking changes.
Versions normally match Raylib's own, with the minor number incremented for any patches (i.e. 5.5.1 for Raylib v5.5). On occasion, if enough breaking changes are made in between Raylib releases, we'll release a 5.6, which is 5.5 but with breaking changes.

# Installation

Expand Down Expand Up @@ -124,7 +124,7 @@ The `raygui.h` file has to have this ifdef modified to point to where `raylib.h`
# Safe Binding characteristics
- Resources are automatically cleaned up when they go out of scope (or when `std::mem::drop` is called). This is essentially RAII. This means that "Unload" functions are not exposed (and not necessary unless you obtain a `Weak` resource using make_weak()).
- Most of the Raylib API is exposed through `RaylibHandle`, which is for enforcing that Raylib is only initialized once, and for making sure the window is closed properly. RaylibHandle has no size and goes away at compile time. Because of mutability rules, Raylib-rs is thread safe!
- A `RaylibHandle` and `RaylibThread` are obtained through `raylib::init_window(...)` or through the newer `init()` function which will allow you to `build` up some window options before initialization (replaces `set_config_flags`). RaylibThread should not be sent to any other threads, or used in a any syncronization primitives (Mutex, Arc) etc.
- A `RaylibHandle` and `RaylibThread` are obtained through `raylib::init_window(...)` or through the newer `init()` function which will allow you to `build` up some window options before initialization (replaces `set_config_flags`). RaylibThread should not be sent to any other threads, or used in a any synchronization primitives (Mutex, Arc) etc.
- Manually closing the window is unnecessary, because `CloseWindow` is automatically called when `RaylibHandle` goes out of scope.
- `Model::set_material`, `Material::set_shader`, and `MaterialMap::set_texture` methods were added since one cannot set the fields directly. Also enforces correct ownership semantics.
- `Font::from_data`, `Font::set_chars`, and `Font::set_texture` methods were added to create a `Font` from loaded `CharInfo` data.
Expand All @@ -139,6 +139,7 @@ The `raygui.h` file has to have this ifdef modified to point to where `raylib.h`
- In C, `LoadDroppedFiles` returns a pointer to an array of strings owned by raylib. Again, for safety and also ease of use, this binding copies said array into a `Vec<String>` which is returned to the caller.
- I've tried to make linking automatic, though I've only tested on Windows 10, Ubuntu, and MacOS 15. Other platforms may have other considerations.
- OpenGL 3.3, 2.1, and ES 2.0 may be forced via adding `["opengl_33"]`, `["opengl_21"]` or `["opengl_es_20]` to the `features` array in your Cargo.toml dependency definition.
- DRM build to render graphics in a tty can be enabled by adding `["drm", "opengl_es_20"]` to `features`. Note that `drm` should usually be used together with `opengl_es_20`.

# Testing

Expand Down
2 changes: 1 addition & 1 deletion checklist.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ RLAPI void DisableEventWaiting(void); // Disable wai

// Custom frame control functions
// NOTE: Those functions are intended for advance users that want full control over the frame processing
// By default EndDrawing() does this job: draws everything + SwapScreenBuffer() + manage frame timming + PollInputEvents()
// By default EndDrawing() does this job: draws everything + SwapScreenBuffer() + manage frame timing + PollInputEvents()
// To avoid that behaviour and control frame processes manually, enable in config.h: SUPPORT_CUSTOM_FRAME_CONTROL
RLAPI void SwapScreenBuffer(void); // Swap back buffer with front buffer (screen drawing)
RLAPI void PollInputEvents(void); // Register all input events
Expand Down
2 changes: 2 additions & 0 deletions raylib-sys/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,8 @@ opengl_es_20 = []
opengl_es_30 = []
sdl = []
wayland = []
legacy_rpi = []
drm = []

# extra build profiles:
release_with_debug_info = []
Expand Down
3 changes: 3 additions & 0 deletions raylib-sys/binding/nobuild.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
#include "raylib.h"
#include "raymath.h"
#include "rlgl.h"
68 changes: 50 additions & 18 deletions raylib-sys/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ impl ParseCallbacks for TypeOverrideCallback {
DeriveTrait::Debug,
DeriveTrait::PartialEqOrPartialOrd,
];
let overriden_types = [
let overridden_types = [
"Vector2",
"Vector3",
"Vector4",
Expand All @@ -68,7 +68,7 @@ impl ParseCallbacks for TypeOverrideCallback {
"Color",
];

(OK_TRAITS.contains(&derive_trait) && overriden_types.contains(&name))
(OK_TRAITS.contains(&derive_trait) && overridden_types.contains(&name))
.then_some(ImplementsTrait::Yes)
}
}
Expand All @@ -81,6 +81,9 @@ fn build_with_cmake(src_path: &str) {
// CMake uses different lib directories on different systems.
// I do not know how CMake determines what directory to use,
// so we will check a few possibilities and use whichever is present.
if is_directory_empty(src_path) {
panic!("raylib source does not exist in: `raylib-sys/raylib`. Please copy it in");
}
fn join_cmake_lib_directory(path: PathBuf) -> PathBuf {
let possible_cmake_lib_directories = ["lib", "lib64", "lib32"];
for lib_directory in &possible_cmake_lib_directories {
Expand Down Expand Up @@ -169,6 +172,7 @@ fn build_with_cmake(src_path: &str) {
}
}
Platform::Web => conf.define("PLATFORM", "Web"),
Platform::DRM => conf.define("PLATFORM", "DRM"),
Platform::RPI => conf.define("PLATFORM", "Raspberry Pi"),
Platform::Android => {
// get required env variables
Expand Down Expand Up @@ -256,6 +260,7 @@ fn gen_bindings() {

let plat = match platform {
Platform::Desktop => "-DPLATFORM_DESKTOP",
Platform::DRM => "-DPLATFORM_DRM",
Platform::RPI => "-DPLATFORM_RPI",
Platform::Android => "-DPLATFORM_ANDROID",
Platform::Web => "-DPLATFORM_WEB",
Expand All @@ -274,8 +279,17 @@ fn gen_bindings() {
.collect(),
);

let header;
#[cfg(feature = "nobuild")]
{
header = "binding/nobuild.h"
}
#[cfg(not(feature = "nobuild"))]
{
header = "binding/binding.h"
}
let mut builder = bindgen::Builder::default()
.header("binding/binding.h")
.header(header)
.rustified_enum(".+")
.derive_partialeq(true)
.derive_default(true)
Expand Down Expand Up @@ -336,7 +350,9 @@ fn gen_utils() {
}

#[cfg(feature = "nobuild")]
fn link(_platform: Platform, _platform_os: PlatformOS) {}
fn link(_platform: Platform, _platform_os: PlatformOS) {
println!("cargo:rustc-link-lib=dylib=raylib");
}

#[cfg(not(feature = "nobuild"))]
fn link(platform: Platform, platform_os: PlatformOS) {
Expand All @@ -349,7 +365,7 @@ fn link(platform: Platform, platform_os: PlatformOS) {
}
PlatformOS::Linux => {
// X11 linking
#[cfg(all(not(feature = "wayland"), target_os = "android"))]
#[cfg(not(any(feature = "wayland", target_os = "android", feature = "drm")))]
{
println!("cargo:rustc-link-search=/usr/local/lib");
println!("cargo:rustc-link-lib=X11");
Expand All @@ -375,6 +391,10 @@ fn link(platform: Platform, platform_os: PlatformOS) {
}
if platform == Platform::Web {
println!("cargo:rustc-link-lib=glfw");
} else if platform == Platform::DRM {
println!("cargo:rustc-link-lib=EGL");
println!("cargo:rustc-link-lib=drm");
println!("cargo:rustc-link-lib=gbm");
} else if platform == Platform::RPI {
println!("cargo:rustc-link-search=/opt/vc/lib");
println!("cargo:rustc-link-lib=bcm_host");
Expand All @@ -387,8 +407,17 @@ fn link(platform: Platform, platform_os: PlatformOS) {
}

fn main() {
let header;
#[cfg(feature = "nobuild")]
{
header = "/usr/include/raylib.h"
}
#[cfg(not(feature = "nobuild"))]
{
header = "binding/binding.h"
}
println!("cargo:rerun-if-changed=build.rs");
println!("cargo:rerun-if-changed=./binding/binding.h");
println!("cargo:rerun-if-changed={header}");
//for cross compiling on switch arm
//https://users.rust-lang.org/t/cross-compiling-arm/96456/10
if std::env::var("CROSS_SYSROOT").is_ok() {
Expand Down Expand Up @@ -424,19 +453,19 @@ fn main() {
let (platform, platform_os) = platform_from_target(&target);

let raylib_src = "./raylib";
if is_directory_empty(raylib_src) {
panic!("raylib source does not exist in: `raylib-sys/raylib`. Please copy it in");
}
build_with_cmake(raylib_src);

gen_bindings();

link(platform, platform_os);

#[cfg(feature = "raygui")]
gen_rgui();
#[cfg(feature = "raygui")] {
gen_rgui();
}

gen_utils();
#[cfg(not(feature = "nobuild"))] {
gen_utils();
}
}

#[must_use]
Expand All @@ -449,10 +478,12 @@ fn is_directory_empty(path: &str) -> bool {
}

fn platform_from_target(target: &str) -> (Platform, PlatformOS) {
let platform = if target.contains("wasm") {
Platform::Web
} else if target.contains("armv7-unknown-linux") {
let platform = if cfg!(feature = "drm") {
Platform::DRM
} else if cfg!(feature = "legacy_rpi") {
Platform::RPI
} else if target.contains("wasm") {
Platform::Web
} else if target.contains("android") {
Platform::Android
} else {
Expand Down Expand Up @@ -483,7 +514,7 @@ fn platform_from_target(target: &str) -> (Platform, PlatformOS) {
_ => panic!("Unknown platform {}", uname()),
}
}
} else if matches!(platform, Platform::RPI | Platform::Android) {
} else if matches!(platform, Platform::DRM | Platform::RPI | Platform::Android) {
let un: &str = &uname();
if un == "Linux" {
PlatformOS::Linux
Expand Down Expand Up @@ -514,7 +545,8 @@ enum Platform {
Web,
Desktop,
Android,
RPI, // raspberry pi
DRM,
RPI, // legacy raspberry pi
}

#[derive(Clone, Copy, Debug, PartialEq)]
Expand All @@ -527,7 +559,7 @@ enum PlatformOS {
}

/// Copied from https://github.com/raysan5/raylib/wiki/CMake-Build-Options and https://github.com/raysan5/raylib/blob/master/src/config.h
/// You should be copy pasting into both raylib/raylib-sys `Cargo.toml` and here while keeping it as close as possible to raylibs `config.h`` for easy maintance
/// You should be copy pasting into both raylib/raylib-sys `Cargo.toml` and here while keeping it as close as possible to raylibs `config.h`` for easy maintenance
#[rustfmt::skip]
fn features_from_env(cmake: &mut Config) {
let is_android = cfg!(target_os = "android"); // skip linking to x11 & wayland
Expand Down
2 changes: 1 addition & 1 deletion raylib-sys/raylib
Submodule raylib updated 631 files
2 changes: 1 addition & 1 deletion raylib-sys/src/color.rs
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,7 @@ impl Color {
}

/// NOTE(IOI_XD): We manually implement PartialEq as of 5.5 to use Raylib's function. It's very unlikely it will ever
/// change or do anything different, but in the ultra rare case that it does, we want to mimick Raylib's behavior.
/// change or do anything different, but in the ultra rare case that it does, we want to mimic Raylib's behavior.
impl PartialEq for Color {
fn eq(&self, other: &Self) -> bool {
return self.is_equal(other);
Expand Down
2 changes: 1 addition & 1 deletion raylib-test/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ repository = "https://github.com/raylib-rs/raylib-rs"

[dependencies]
raylib = { version = "5.7.0", path = "../raylib" }
raylib_sys = { version = "5.7.0", path = "../raylib-sys" }
raylib-sys = { version = "5.7.0", path = "../raylib-sys" }
lazy_static = "1.2.0"
colored = "1.9.1"

Expand Down
File renamed without changes.
2 changes: 1 addition & 1 deletion raylib-test/src/automation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ pub(crate) mod automation_test {
let mut events = aelist.events();

while !rl.window_should_close() {
rl.update_camera(&mut camera, CameraMode::CAMERA_FIRST_PERSON);
camera.update_camera(CameraMode::CAMERA_FIRST_PERSON);

if rl.is_key_released(KeyboardKey::KEY_SPACE) {
if !is_recording {
Expand Down
14 changes: 4 additions & 10 deletions raylib-test/src/callbacks.rs
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ pub mod callback_tests {
let mut handle = TEST_HANDLE.write().unwrap();
let rl = handle.as_mut().unwrap();
{
rl.set_trace_log_callback(custom_callback).unwrap();
set_trace_log_callback(custom_callback).unwrap();
for _ in 0..5 {
let noise = Image::gen_image_white_noise(10, 10, 1.0);
let _ = rl.load_texture_from_image(&thread, &noise).unwrap();
Expand All @@ -115,10 +115,8 @@ pub mod callback_tests {
"\n{}\n",
"Setting file data saver callback".bold().underline(),
);
let mut handle = TEST_HANDLE.write().unwrap();
let rl = handle.as_mut().unwrap();
{
rl.set_save_file_data_callback(custom_save_file_data_callback)
set_save_file_data_callback(custom_save_file_data_callback)
.unwrap();
}
}
Expand All @@ -128,10 +126,8 @@ pub mod callback_tests {
"\n{}\n",
"Setting file text saver callback".bold().underline(),
);
let mut handle = TEST_HANDLE.write().unwrap();
let rl = handle.as_mut().unwrap();
{
rl.set_save_file_text_callback(custom_save_file_text_callback)
set_save_file_text_callback(custom_save_file_text_callback)
.unwrap();
}
}
Expand All @@ -141,10 +137,8 @@ pub mod callback_tests {
"\n{}\n",
"Setting file data loader callback".bold().underline(),
);
let mut handle = TEST_HANDLE.write().unwrap();
let rl = handle.as_mut().unwrap();
{
rl.set_load_file_data_callback(custom_read_file_data_callback)
set_load_file_data_callback(custom_read_file_data_callback)
.unwrap();
}
}
Expand Down
41 changes: 32 additions & 9 deletions raylib-test/src/data.rs
Original file line number Diff line number Diff line change
@@ -1,14 +1,10 @@
#[cfg(test)]
mod data_test {
use crate::tests::*;
use colored::Colorize;
use raylib::prelude::*;

ray_test!(data_test);
fn data_test(_: &RaylibThread) {
//let mut handle = TEST_HANDLE.write().unwrap();
//let rl = handle.as_mut().unwrap();

export_data_as_code(
"The quick brown fox jumped over the lazy dog.".as_bytes(),
"./test_out/export_data.txt",
Expand All @@ -18,10 +14,37 @@ mod data_test {
ray_test!(base64);
fn base64(_: &RaylibThread) {
let encoded = encode_data_base64("This is a test".as_bytes());
let enc: Vec<u8> = encoded.to_vec().iter().map(|f| *f as u8).collect();
let decoded = decode_data_base64(&enc);

let enc: Vec<u8> = encoded.expect("encode ok").to_vec().iter().map(|f| *f as u8).collect();
let decoded = decode_data_base64(&enc).expect("decode ok");
let fin = std::str::from_utf8(&decoded).unwrap();
assert!(fin == "This is a test")
assert_eq!(fin, "This is a test")
}

ray_test!(base64_encode_and_decode);
fn base64_encode_and_decode(_: &RaylibThread) {
let encoded = encode_data_base64(b"This is a test").expect("encode ok");
let mut enc = encoded.as_ref();
if enc.ends_with(&[0]) {
enc = &enc[..enc.len() - 1];
}
let decoded = decode_data_base64(enc).expect("decode ok");
assert_eq!(decoded.as_ref(), b"This is a test");
}

ray_test!(base64_decode_plain_str);
fn base64_decode_plain_str(_: &RaylibThread) {
//non-trailing null
let str = b"VGhpcyBpcyBhIHRlc3Q=";
let out = decode_data_base64(str).expect("decode plain ok");
assert_eq!(out.as_ref(), b"This is a test");
}

ray_test!(base64_decode_with_trailing_null);
fn base64_decode_with_trailing_null(_: &RaylibThread) {
// trailing null
let mut c_str = b"SGVsbG8sIHdvcmxkIQ==".to_vec();
c_str.push(0);
let out = decode_data_base64(&c_str).expect("decode c-string ok");
assert_eq!(out.as_ref(), b"Hello, world!");
}
}
}
Loading
Loading