mirror of
https://github.com/encounter/rust-sdl2.git
synced 2026-07-10 21:18:41 -07:00
+28
-38
@@ -1,47 +1,37 @@
|
||||
language: rust
|
||||
sudo: required
|
||||
rust:
|
||||
- beta
|
||||
- nightly
|
||||
- stable
|
||||
- beta
|
||||
- nightly
|
||||
- stable
|
||||
os:
|
||||
- linux
|
||||
- osx
|
||||
- linux
|
||||
- osx
|
||||
env:
|
||||
matrix:
|
||||
- CI_BUILD_FEATURES="bundled"
|
||||
- CI_BUILD_FEATURES="gfx image ttf mixer"
|
||||
global:
|
||||
- RUST_TEST_THREADS=1
|
||||
- TRAVIS_CARGO_NIGHTLY_FEATURE=""
|
||||
- LD_LIBRARY_PATH: "/usr/local/lib"
|
||||
- secure: MJhmVnQ2IM7+sVmc3vU4ndKOcQgLLeHUPW3qaQBQHKQmvoswCwQK60N17uSgWn1Ln8teqvSRHq4KclIjdMHI+VuQXJHQKHDgjcYbHxwmc3AM1Whnp0XB44ksKUmD109BGWSfZQxzF+6dA+YNOQ+mti+bpydMu8n2FMVjA/SXwQ8=
|
||||
|
||||
install:
|
||||
- wget https://www.libsdl.org/release/SDL2-2.0.8.tar.gz -O sdl2.tar.gz
|
||||
- tar xzf sdl2.tar.gz
|
||||
- pushd SDL2-* && ./configure && make && sudo make install && popd
|
||||
- wget -q https://www.libsdl.org/projects/SDL_ttf/release/SDL2_ttf-2.0.14.tar.gz
|
||||
- wget -q https://www.libsdl.org/projects/SDL_image/release/SDL2_image-2.0.1.tar.gz
|
||||
- wget -q https://www.libsdl.org/projects/SDL_mixer/release/SDL2_mixer-2.0.1.tar.gz
|
||||
- wget -q -O SDL2_gfx-1.0.1.tar.gz https://sourceforge.net/projects/sdl2gfx/files/SDL2_gfx-1.0.1.tar.gz/download
|
||||
- tar xzf SDL2_ttf-*.tar.gz
|
||||
- tar xzf SDL2_image-*.tar.gz
|
||||
- tar xzf SDL2_mixer-*.tar.gz
|
||||
- tar xzf SDL2_gfx-*.tar.gz
|
||||
- pushd SDL2_ttf-* && ./configure && make && sudo make install && popd
|
||||
- pushd SDL2_image-* && ./configure && make && sudo make install && popd
|
||||
- pushd SDL2_mixer-* && ./configure && make && sudo make install && popd
|
||||
- pushd SDL2_gfx-* && ./autogen.sh && ./configure && make && sudo make install && popd
|
||||
- if [[ $CI_BUILD_FEATURES != *"bundled"* ]]; then bash scripts/travis-install-sdl2.sh; fi
|
||||
|
||||
before_script:
|
||||
- shopt -s expand_aliases
|
||||
- if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then alias pip=pip2; fi
|
||||
- |
|
||||
pip install 'travis-cargo<0.2' --user &&
|
||||
export PATH=$HOME/.local/bin:$PATH &&
|
||||
export PATH=~/Library/Python/2.7/bin:$PATH
|
||||
- shopt -s expand_aliases
|
||||
- if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then alias pip=pip2; fi
|
||||
- |
|
||||
pip install 'travis-cargo<0.2' --user &&
|
||||
export PATH=$HOME/.local/bin:$PATH &&
|
||||
export PATH=~/Library/Python/2.7/bin:$PATH
|
||||
script:
|
||||
- |
|
||||
travis-cargo build -- --features "gfx image ttf mixer" &&
|
||||
travis-cargo build -- --examples --features "gfx image ttf mixer" &&
|
||||
travis-cargo test -- --features "gfx image ttf mixer" &&
|
||||
travis-cargo --only stable doc -- --features "gfx image ttf mixer"
|
||||
- |
|
||||
travis-cargo build -- --features "${CI_BUILD_FEATURES}" &&
|
||||
travis-cargo build -- --examples --features "${CI_BUILD_FEATURES}" &&
|
||||
travis-cargo test -- --features "${CI_BUILD_FEATURES}" &&
|
||||
travis-cargo --only stable doc -- --features "${CI_BUILD_FEATURES}"
|
||||
after_success:
|
||||
- travis-cargo --only stable doc-upload
|
||||
env:
|
||||
global:
|
||||
- RUST_TEST_THREADS=1
|
||||
- TRAVIS_CARGO_NIGHTLY_FEATURE=""
|
||||
- LD_LIBRARY_PATH: "/usr/local/lib"
|
||||
- secure: MJhmVnQ2IM7+sVmc3vU4ndKOcQgLLeHUPW3qaQBQHKQmvoswCwQK60N17uSgWn1Ln8teqvSRHq4KclIjdMHI+VuQXJHQKHDgjcYbHxwmc3AM1Whnp0XB44ksKUmD109BGWSfZQxzF+6dA+YNOQ+mti+bpydMu8n2FMVjA/SXwQ8=
|
||||
- travis-cargo --only stable doc-upload
|
||||
|
||||
+7
-7
@@ -4,11 +4,11 @@ name = "sdl2"
|
||||
description = "SDL2 bindings for Rust"
|
||||
repository = "https://github.com/Rust-SDL2/rust-sdl2"
|
||||
documentation = "https://rust-sdl2.github.io/rust-sdl2/sdl2/"
|
||||
version = "0.31.0"
|
||||
version = "0.32.0-beta.2"
|
||||
license = "MIT"
|
||||
authors = [ "Tony Aldridge <tony@angry-lawyer.com>", "Cobrand <cobrandw@gmail.com>"]
|
||||
keywords = ["SDL", "windowing", "graphics", "api"]
|
||||
categories = ["rendering","games","api-bindings","game-engines","multimedia"]
|
||||
keywords = ["SDL", "windowing", "graphics", "api", "engine"]
|
||||
categories = ["rendering","api-bindings","game-engines","multimedia"]
|
||||
|
||||
[lib]
|
||||
|
||||
@@ -17,9 +17,9 @@ path = "src/sdl2/lib.rs"
|
||||
|
||||
[dependencies]
|
||||
bitflags = "0.7"
|
||||
libc = "0.2"
|
||||
rand = "0.3"
|
||||
lazy_static="0.2"
|
||||
libc = "^0.2"
|
||||
rand = "^0.5"
|
||||
lazy_static = "^1"
|
||||
|
||||
[dependencies.num]
|
||||
version = "0.1"
|
||||
@@ -27,7 +27,7 @@ default-features = false
|
||||
|
||||
[dependencies.sdl2-sys]
|
||||
path = "sdl2-sys"
|
||||
version = "0.31.0"
|
||||
version = "0.32.1"
|
||||
|
||||
[dependencies.c_vec]
|
||||
version = ">= 1.0, <= 1.3"
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
Bindings for SDL2 in Rust
|
||||
|
||||
### [Changelog for 0.31](changelog.md#v031)
|
||||
### [Changelog for 0.32](changelog.md#v032)
|
||||
|
||||
# Overview
|
||||
|
||||
@@ -257,7 +257,7 @@ download through Crates.io:
|
||||
|
||||
```toml
|
||||
[dependencies]
|
||||
sdl2 = "0.31"
|
||||
sdl2 = "0.32"
|
||||
```
|
||||
|
||||
Alternatively, pull it from GitHub to obtain the latest version from master
|
||||
@@ -278,7 +278,7 @@ adding this instead:
|
||||
|
||||
```toml
|
||||
[dependencies.sdl2]
|
||||
version = "0.31"
|
||||
version = "0.32"
|
||||
default-features = false
|
||||
features = ["ttf","image","gfx","mixer"]
|
||||
```
|
||||
@@ -459,6 +459,58 @@ fn main() {
|
||||
This method is useful when you don't care about sdl2's render capabilities, but you do care about
|
||||
its audio, controller and other neat features that sdl2 has.
|
||||
|
||||
# Vulkan
|
||||
|
||||
To use Vulkan, you need a Vulkan library for Rust. This example uses the
|
||||
[Vulkano](https://github.com/vulkano-rs/vulkano) library. Other libraries may use different data
|
||||
types for raw Vulkan object handles. The procedure to interface SDL2's Vulkan functions with these
|
||||
will be different for each one.
|
||||
|
||||
```rust
|
||||
extern crate sdl2;
|
||||
extern crate vulkano;
|
||||
|
||||
use sdl2::event::Event;
|
||||
use sdl2::keyboard::Keycode;
|
||||
use std::ffi::CString;
|
||||
use vulkano::VulkanObject;
|
||||
use vulkano::instance::{Instance, RawInstanceExtensions};
|
||||
use vulkano::swapchain::Surface;
|
||||
|
||||
fn main() {
|
||||
let sdl_context = sdl2::init().unwrap();
|
||||
let video_subsystem = sdl_context.video().unwrap();
|
||||
|
||||
let window = video_subsystem.window("Window", 800, 600)
|
||||
.vulkan()
|
||||
.build()
|
||||
.unwrap();
|
||||
|
||||
let instance_extensions = window.vulkan_instance_extensions().unwrap();
|
||||
let raw_instance_extensions = RawInstanceExtensions::new(instance_extensions.iter().map(
|
||||
|&v| CString::new(v).unwrap()
|
||||
));
|
||||
let instance = Instance::new(None, raw_instance_extensions, None).unwrap();
|
||||
let surface_handle = window.vulkan_create_surface(instance.internal_object()).unwrap();
|
||||
let surface = unsafe { Surface::from_raw_surface(instance, surface_handle, window.context()) };
|
||||
|
||||
let mut event_pump = sdl_context.event_pump().unwrap();
|
||||
|
||||
'running: loop {
|
||||
for event in event_pump.poll_iter() {
|
||||
match event {
|
||||
Event::Quit {..} | Event::KeyDown { keycode: Some(Keycode::Escape), .. } => {
|
||||
break 'running
|
||||
},
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
::std::thread::sleep(::std::time::Duration::new(0, 1_000_000_000u32 / 60));
|
||||
}
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
# When things go wrong
|
||||
Rust, and Rust-SDL2, are both still heavily in development, and you may run
|
||||
into teething issues when using this. Before panicking, check that you're using
|
||||
|
||||
+38
-7
@@ -1,16 +1,47 @@
|
||||
In this file will be listed the changes, especially the breaking ones that one should be careful of
|
||||
when upgrading from a version of rust-sdl2 to another.
|
||||
|
||||
### v0.31.1
|
||||
### v0.32
|
||||
|
||||
[PR #737](https://github.com/Rust-SDL2/rust-sdl2/pull/737)
|
||||
* Fix `ClipboardUtil::set_clipboard_text` to return an Ok when it went well.
|
||||
[PR #790](https://github.com/Rust-SDL2/rust-sdl2/pull/790): Added missing `window_id` field to `Event::DropFile`
|
||||
|
||||
[PR #733](https://github.com/Rust-SDL2/rust-sdl2/pull/733)
|
||||
* Add `video::border_size -> Result<(u16, u16, u16, u16), String>` equivalent of `SDL_GetWindowBorderSize()`
|
||||
[PR #789](https://github.com/Rust-SDL2/rust-sdl2/pull/789): Audio Safety Fixes
|
||||
|
||||
[PR #732](https://github.com/Rust-SDL2/rust-sdl2/pull/732)
|
||||
* Implemented `From<(u8, u8, u8)>` and `From<(u8, u8, u8, u8)>` for `pixels::Color`.
|
||||
[PR #785](https://github.com/Rust-SDL2/rust-sdl2/pull/785): Vulkan Support
|
||||
|
||||
[PR #782](https://github.com/Rust-SDL2/rust-sdl2/pull/782)
|
||||
* Move ffi of features (mixer, ...) into `sys`
|
||||
* Updated SDL2's default version to 2.0.8
|
||||
|
||||
[PR #780](https://github.com/Rust-SDL2/rust-sdl2/pull/780): Fixed a panic in `keyboard::Mod`
|
||||
|
||||
[PR #775](https://github.com/Rust-SDL2/rust-sdl2/pull/775): Added `get_platform`
|
||||
|
||||
[PR #774](https://github.com/Rust-SDL2/rust-sdl2/pull/774): `add_timer` is now must_use
|
||||
|
||||
[PR #764](https://github.com/Rust-SDL2/rust-sdl2/pull/764): impl `Hash` for `Point` and `Rect`
|
||||
|
||||
[PR #763](https://github.com/Rust-SDL2/rust-sdl2/pull/763): Allow `-sys` to build for `windows-gnu` target
|
||||
|
||||
[PR #751](https://github.com/Rust-SDL2/rust-sdl2/pull/751):
|
||||
**Breaking change** `gl_setswap_interval` now returns a `Result` instead of a `bool`.
|
||||
|
||||
[PR #759](https://github.com/Rust-SDL2/rust-sdl2/pull/759): Expose Joystick power level
|
||||
|
||||
[PR #751](https://github.com/Rust-SDL2/rust-sdl2/pull/751)
|
||||
* Fix memory leak in `filesystem::base_path()`
|
||||
* Fix memory leak on `ClipboardUtil::clipboard_text()`
|
||||
|
||||
[PR #740](https://github.com/Rust-SDL2/rust-sdl2/pull/740): Implement Debug for Event
|
||||
|
||||
[PR #737](https://github.com/Rust-SDL2/rust-sdl2/pull/737):
|
||||
Fix `ClipboardUtil::set_clipboard_text` to return an Ok when it went well.
|
||||
|
||||
[PR #733](https://github.com/Rust-SDL2/rust-sdl2/pull/733):
|
||||
Add `video::border_size -> Result<(u16, u16, u16, u16), String>` equivalent of `SDL_GetWindowBorderSize()`
|
||||
|
||||
[PR #732](https://github.com/Rust-SDL2/rust-sdl2/pull/732):
|
||||
Implemented `From<(u8, u8, u8)>` and `From<(u8, u8, u8, u8)>` for `pixels::Color`.
|
||||
`Canvas.set_draw_color` can now be called with tuples or other types which implements `Into<pixels::Color>`
|
||||
|
||||
[PR #279](https://github.com/Rust-SDL2/rust-sdl2/pull/729)
|
||||
|
||||
@@ -16,7 +16,7 @@ impl AudioCallback for MyCallback {
|
||||
|
||||
// Generate white noise
|
||||
for x in out.iter_mut() {
|
||||
*x = (rng.next_f32()*2.0 - 1.0) * self.volume;
|
||||
*x = (rng.gen_range(0.0, 2.0) - 1.0) * self.volume;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
set -xueo pipefail
|
||||
|
||||
wget https://www.libsdl.org/release/SDL2-2.0.8.tar.gz -O sdl2.tar.gz
|
||||
tar xzf sdl2.tar.gz
|
||||
pushd SDL2-* && ./configure && make && sudo make install && popd
|
||||
wget -q https://www.libsdl.org/projects/SDL_ttf/release/SDL2_ttf-2.0.14.tar.gz
|
||||
wget -q https://www.libsdl.org/projects/SDL_image/release/SDL2_image-2.0.1.tar.gz
|
||||
wget -q https://www.libsdl.org/projects/SDL_mixer/release/SDL2_mixer-2.0.2.tar.gz
|
||||
wget -q -O SDL2_gfx-1.0.1.tar.gz https://sourceforge.net/projects/sdl2gfx/files/SDL2_gfx-1.0.1.tar.gz/download
|
||||
tar xzf SDL2_ttf-*.tar.gz
|
||||
tar xzf SDL2_image-*.tar.gz
|
||||
tar xzf SDL2_mixer-*.tar.gz
|
||||
tar xzf SDL2_gfx-*.tar.gz
|
||||
pushd SDL2_ttf-* && ./configure && make && sudo make install && popd
|
||||
pushd SDL2_image-* && ./configure && make && sudo make install && popd
|
||||
pushd SDL2_mixer-* && ./configure && make && sudo make install && popd
|
||||
pushd SDL2_gfx-* && ./autogen.sh && ./configure && make && sudo make install && popd
|
||||
+15
-11
@@ -2,11 +2,11 @@
|
||||
|
||||
name = "sdl2-sys"
|
||||
description = "Raw SDL2 bindings for Rust, used internally rust-sdl2"
|
||||
repository = "https://github.com/AngryLawyer/rust-sdl2"
|
||||
version = "0.31.0"
|
||||
repository = "https://github.com/rust-sdl2/rust-sdl2"
|
||||
version = "0.32.1"
|
||||
authors = ["Tony Aldridge <tony@angry-lawyer.com>"]
|
||||
keywords = ["SDL", "windowing", "graphics", "ffi"]
|
||||
categories = ["rendering","games","external-ffi-bindings","game-engines","multimedia"]
|
||||
categories = ["rendering","external-ffi-bindings","game-engines","multimedia"]
|
||||
license = "MIT"
|
||||
links = "SDL2"
|
||||
build = "build.rs"
|
||||
@@ -16,31 +16,35 @@ name = "sdl2_sys"
|
||||
path = "src/lib.rs"
|
||||
|
||||
[build-dependencies.bindgen]
|
||||
version = "0.35"
|
||||
version = "^0.42"
|
||||
optional = true
|
||||
|
||||
[build-dependencies.pkg-config]
|
||||
version = "0.3.9"
|
||||
version = "^0.3"
|
||||
optional = true
|
||||
|
||||
[build-dependencies.cmake]
|
||||
version = "0.1"
|
||||
version = "^0.1"
|
||||
optional = true
|
||||
|
||||
[build-dependencies.reqwest]
|
||||
version = "0.7"
|
||||
version = "^0.9"
|
||||
optional = true
|
||||
|
||||
[build-dependencies.tar]
|
||||
version = "0.4"
|
||||
version = "^0.4"
|
||||
optional = true
|
||||
|
||||
[build-dependencies.flate2]
|
||||
version = "0.2"
|
||||
version = "^1"
|
||||
optional = true
|
||||
|
||||
[build-dependencies.unidiff]
|
||||
version = "^0.2"
|
||||
optional = true
|
||||
|
||||
[build-dependencies]
|
||||
cfg-if = "0.1"
|
||||
cfg-if = "^0.1"
|
||||
|
||||
[features]
|
||||
|
||||
@@ -49,7 +53,7 @@ use-pkgconfig = ["pkg-config"]
|
||||
use-bindgen = ["bindgen"]
|
||||
static-link = []
|
||||
use_mac_framework = []
|
||||
bundled = ["cmake", "reqwest", "tar", "flate2"]
|
||||
bundled = ["cmake", "reqwest", "tar", "flate2", "unidiff"]
|
||||
mixer = []
|
||||
image = []
|
||||
ttf = []
|
||||
|
||||
+183
-7
@@ -12,6 +12,8 @@ extern crate tar;
|
||||
extern crate flate2;
|
||||
#[cfg(feature="bundled")]
|
||||
extern crate reqwest;
|
||||
#[cfg(feature="bundled")]
|
||||
extern crate unidiff;
|
||||
|
||||
#[macro_use]
|
||||
extern crate cfg_if;
|
||||
@@ -20,10 +22,10 @@ use std::path::{Path, PathBuf};
|
||||
use std::{io, fs, env};
|
||||
|
||||
// corresponds to the headers that we have in sdl2-sys/SDL2-{version}
|
||||
const SDL2_HEADERS_BUNDLED_VERSION: &str = "2.0.8";
|
||||
const SDL2_HEADERS_BUNDLED_VERSION: &str = "2.0.5";
|
||||
|
||||
// means the lastest stable version that can be downloaded from SDL2's source
|
||||
const LASTEST_SDL2_VERSION: &str = "2.0.8";
|
||||
const LASTEST_SDL2_VERSION: &str = "2.0.5";
|
||||
|
||||
#[cfg(feature = "bindgen")]
|
||||
macro_rules! add_msvc_includes_to_bindings {
|
||||
@@ -41,9 +43,13 @@ fn download_to<T: io::Write>(url: &str, mut dest: T) {
|
||||
use io::BufRead;
|
||||
|
||||
let resp = reqwest::get(url).expect(&format!("Failed to GET resource: {:?}", url));
|
||||
let size = resp.headers()
|
||||
.get::<reqwest::header::ContentLength>()
|
||||
.map(|ct_len| **ct_len)
|
||||
let size: u32 = resp.headers()
|
||||
.get(reqwest::header::CONTENT_LENGTH)
|
||||
.and_then(|cl| {
|
||||
cl.to_str().ok().and_then(|cl| {
|
||||
cl.parse::<u32>().ok()
|
||||
})
|
||||
})
|
||||
.unwrap_or(0);
|
||||
if !resp.status().is_success() { panic!("Download request failed with status: {:?}", resp.status()) }
|
||||
if size == 0 { panic!("Size of content was returned was 0") }
|
||||
@@ -105,13 +111,133 @@ fn download_sdl2() -> PathBuf {
|
||||
|
||||
let reader = flate2::read::GzDecoder::new(
|
||||
fs::File::open(&sdl2_archive_path).unwrap()
|
||||
).unwrap();
|
||||
);
|
||||
let mut ar = tar::Archive::new(reader);
|
||||
ar.unpack(&out_dir).unwrap();
|
||||
|
||||
sdl2_build_path
|
||||
}
|
||||
|
||||
// apply patches to sdl2 source
|
||||
#[cfg(feature = "bundled")]
|
||||
fn patch_sdl2(sdl2_source_path: &Path) {
|
||||
// vector of <(patch_file_name, patch_file_contents)>
|
||||
let patches: Vec<(&str, &'static str)> = vec![
|
||||
// This patch fixes a CMake installation bug introduced in SDL2 2.0.4 on
|
||||
// the Mac OS platform. Without this patch, the libSDL2.dylib generated
|
||||
// during the SDL2 build phase will be overwritten by a symlink pointing
|
||||
// to nothing. A variation of this patch was accepted upstream and
|
||||
// should be included in SDL2 2.0.9.
|
||||
// https://bugzilla.libsdl.org/show_bug.cgi?id=4234
|
||||
("SDL2-2.0.8-4234-mac-os-dylib-fix.patch", include_str!("patches/SDL2-2.0.8-4234-mac-os-dylib-fix.patch")),
|
||||
];
|
||||
let sdl_version = format!("SDL2-{}", LASTEST_SDL2_VERSION);
|
||||
|
||||
for patch in &patches {
|
||||
// Only apply patches whose file name is prefixed with the currently
|
||||
// targeted version of SDL2.
|
||||
if !patch.0.starts_with(&sdl_version) {
|
||||
continue;
|
||||
}
|
||||
let mut patch_set = unidiff::PatchSet::new();
|
||||
patch_set.parse(patch.1).expect("Error parsing diff");
|
||||
|
||||
// For every modified file, copy the existing file to <file_name>_old,
|
||||
// open a new copy of <file_name>. and fill the new file with a
|
||||
// combination of the unmodified contents, and the patched sections.
|
||||
// TOOD: This code is untested (save for the immediate application), and
|
||||
// probably belongs in the unidiff (or similar) package.
|
||||
for modified_file in patch_set.modified_files() {
|
||||
use std::io::{Write, BufRead};
|
||||
|
||||
let file_path = sdl2_source_path.join(modified_file.path());
|
||||
let old_path = sdl2_source_path.join(format!("{}_old", modified_file.path()));
|
||||
fs::rename(&file_path, &old_path)
|
||||
.expect(&format!(
|
||||
"Rename of {} to {} failed",
|
||||
file_path.to_string_lossy(),
|
||||
old_path.to_string_lossy()));
|
||||
|
||||
let dst_file = fs::File::create(file_path).unwrap();
|
||||
let mut dst_buf = io::BufWriter::new(dst_file);
|
||||
let old_file = fs::File::open(old_path).unwrap();
|
||||
let mut old_buf = io::BufReader::new(old_file);
|
||||
let mut cursor = 0;
|
||||
|
||||
for (i, hunk) in modified_file.into_iter().enumerate() {
|
||||
// Write old lines from cursor to the start of this hunk.
|
||||
let num_lines = hunk.source_start - cursor - 1;
|
||||
for _ in 0..num_lines {
|
||||
let mut line = String::new();
|
||||
old_buf.read_line(&mut line).unwrap();
|
||||
dst_buf.write_all(line.as_bytes()).unwrap();
|
||||
}
|
||||
cursor += num_lines;
|
||||
|
||||
// Skip lines in old_file, and verify that what we expect to
|
||||
// replace is present in the old_file.
|
||||
for expected_line in hunk.source_lines() {
|
||||
let mut actual_line = String::new();
|
||||
old_buf.read_line(&mut actual_line).unwrap();
|
||||
actual_line.pop(); // Remove the trailing newline.
|
||||
if expected_line.value != actual_line {
|
||||
panic!("Can't apply patch; mismatch between expected and actual in hunk {}", i);
|
||||
}
|
||||
}
|
||||
cursor += hunk.source_length;
|
||||
|
||||
// Write the new lines into the destination.
|
||||
for line in hunk.target_lines() {
|
||||
dst_buf.write_all(line.value.as_bytes()).unwrap();
|
||||
dst_buf.write_all(b"\n").unwrap();
|
||||
}
|
||||
}
|
||||
|
||||
// Write all remaining lines from the old file into the new.
|
||||
for line in old_buf.lines() {
|
||||
dst_buf.write_all(&line.unwrap().into_bytes()).unwrap();
|
||||
dst_buf.write_all(b"\n").unwrap();
|
||||
}
|
||||
}
|
||||
// For every removed file, simply delete the original.
|
||||
// TODO: This is entirely untested code. There are likely bugs here, and
|
||||
// this really should be part of the unidiff library, not a function
|
||||
// defined here. Hopefully this gets moved somewhere else before it
|
||||
// bites someone.
|
||||
for removed_file in patch_set.removed_files() {
|
||||
fs::remove_file(sdl2_source_path.join(removed_file.path()))
|
||||
.expect(
|
||||
&format!("Failed to remove file {} from {}",
|
||||
removed_file.path(),
|
||||
sdl2_source_path.to_string_lossy()));
|
||||
}
|
||||
// For every new file, copy the entire contents of the patched file into
|
||||
// a newly created <file_name>.
|
||||
// TODO: This is entirely untested code. There are likely bugs here, and
|
||||
// this really should be part of the unidiff library, not a function
|
||||
// defined here. Hopefully this gets moved somewhere else before it
|
||||
// bites someone.
|
||||
for added_file in patch_set.added_files() {
|
||||
use std::io::Write;
|
||||
|
||||
// This should be superfluous. I don't know how a new file would
|
||||
// ever have more than one hunk.
|
||||
assert!(added_file.len() == 1);
|
||||
let file_path = sdl2_source_path.join(added_file.path());
|
||||
let mut dst_file = fs::File::create(&file_path)
|
||||
.expect(&format!(
|
||||
"Failed to create file {}",
|
||||
file_path.to_string_lossy()));
|
||||
let mut dst_buf = io::BufWriter::new(&dst_file);
|
||||
|
||||
for line in added_file.into_iter().nth(0).unwrap().target_lines() {
|
||||
dst_buf.write_all(line.value.as_bytes()).unwrap();
|
||||
dst_buf.write_all(b"\n").unwrap();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// compile a shared or static lib depending on the feature
|
||||
#[cfg(feature = "bundled")]
|
||||
fn compile_sdl2(sdl2_build_path: &Path, target_os: &str) -> PathBuf {
|
||||
@@ -281,14 +407,60 @@ fn link_sdl2(target_os: &str) {
|
||||
}
|
||||
}
|
||||
|
||||
fn find_cargo_target_dir() -> PathBuf {
|
||||
// Infer the top level cargo target dir from the OUT_DIR by searching
|
||||
// upwards until we get to $CARGO_TARGET_DIR/build/ (which is always one
|
||||
// level up from the deepest directory containing our package name)
|
||||
let pkg_name = env::var("CARGO_PKG_NAME").unwrap();
|
||||
let mut out_dir = PathBuf::from(env::var("OUT_DIR").unwrap());
|
||||
loop {
|
||||
{
|
||||
let final_path_segment = out_dir.file_name().unwrap();
|
||||
if final_path_segment.to_string_lossy().contains(&pkg_name) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if !out_dir.pop() {
|
||||
panic!("Malformed build path: {}", out_dir.to_string_lossy());
|
||||
}
|
||||
}
|
||||
out_dir.pop();
|
||||
out_dir.pop();
|
||||
out_dir
|
||||
}
|
||||
|
||||
fn copy_dynamic_libraries(sdl2_compiled_path: &PathBuf, target_os: &str) {
|
||||
// Windows binaries do not embed library search paths, so successfully
|
||||
// linking the DLL isn't sufficient to find it at runtime -- it must be
|
||||
// either on PATH or in the current working directory when we run binaries
|
||||
// linked against it. In other words, to run the test suite we need to
|
||||
// copy sdl2.dll out of its build tree and down to the top level cargo
|
||||
// binary output directory.
|
||||
if target_os.contains("windows") {
|
||||
let sdl2_dll_name = "sdl2.dll";
|
||||
let sdl2_bin_path = sdl2_compiled_path.join("bin");
|
||||
let target_path = find_cargo_target_dir();
|
||||
|
||||
let src_dll_path = sdl2_bin_path.join(sdl2_dll_name);
|
||||
let dst_dll_path = target_path.join(sdl2_dll_name);
|
||||
|
||||
fs::copy(&src_dll_path, &dst_dll_path)
|
||||
.expect(&format!("Failed to copy SDL2 dynamic library from {} to {}",
|
||||
src_dll_path.to_string_lossy(),
|
||||
dst_dll_path.to_string_lossy()));
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let target = env::var("TARGET").expect("Cargo build scripts always have TARGET");
|
||||
let host = env::var("HOST").expect("Cargo build scripts always have HOST");
|
||||
let target_os = get_os_from_triple(target.as_str()).unwrap();
|
||||
|
||||
let sdl2_compiled_path: PathBuf;
|
||||
#[cfg(feature = "bundled")] {
|
||||
let sdl2_source_path = download_sdl2();
|
||||
let sdl2_compiled_path = compile_sdl2(sdl2_source_path.as_path(), target_os);
|
||||
patch_sdl2(sdl2_source_path.as_path());
|
||||
sdl2_compiled_path = compile_sdl2(sdl2_source_path.as_path(), target_os);
|
||||
|
||||
let sdl2_downloaded_include_path = sdl2_source_path.join("include");
|
||||
let sdl2_compiled_lib_path = sdl2_compiled_path.join("lib");
|
||||
@@ -311,6 +483,10 @@ fn main() {
|
||||
}
|
||||
|
||||
link_sdl2(target_os);
|
||||
|
||||
#[cfg(all(feature = "bundled", not(feature = "static-link")))] {
|
||||
copy_dynamic_libraries(&sdl2_compiled_path, target_os);
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "bindgen"))]
|
||||
|
||||
@@ -0,0 +1,44 @@
|
||||
# HG changeset patch
|
||||
# User Drew Pirrone-Brusse <drew.pirrone.brusse@gmail.com>
|
||||
# Date 1537744393 14400
|
||||
# Sun Sep 23 19:13:13 2018 -0400
|
||||
# Node ID b66fb83b6897137c1c2b857ee5490e602f8c31b0
|
||||
# Parent f1084c419f33610cf274e309a8b2798d2ae665c7
|
||||
Correct the name of the SDL shared library in CMake for Mac OS
|
||||
|
||||
diff -r f1084c419f33 -r b66fb83b6897 CMakeLists.txt
|
||||
--- a/CMakeLists.txt Thu Mar 01 08:26:10 2018 -0800
|
||||
+++ b/CMakeLists.txt Sun Sep 23 19:13:13 2018 -0400
|
||||
@@ -1704,7 +1704,9 @@
|
||||
if(SDL_SHARED)
|
||||
add_library(SDL2 SHARED ${SOURCE_FILES} ${VERSION_SOURCES})
|
||||
if(APPLE)
|
||||
- set_target_properties(SDL2 PROPERTIES MACOSX_RPATH 1)
|
||||
+ set_target_properties(SDL2 PROPERTIES
|
||||
+ MACOSX_RPATH 1
|
||||
+ OUTPUT_NAME "SDL2-${LT_RELEASE}")
|
||||
elseif(UNIX AND NOT ANDROID)
|
||||
set_target_properties(SDL2 PROPERTIES
|
||||
VERSION ${LT_VERSION}
|
||||
@@ -1810,16 +1812,14 @@
|
||||
|
||||
if(NOT (WINDOWS OR CYGWIN))
|
||||
if(SDL_SHARED)
|
||||
- if (APPLE)
|
||||
- set(SOEXT "dylib")
|
||||
- else()
|
||||
- set(SOEXT "so")
|
||||
- endif()
|
||||
+ set(SOEXT ${CMAKE_SHARED_LIBRARY_SUFFIX}) # ".so", ".dylib", etc.
|
||||
+ get_target_property(SONAME SDL2 OUTPUT_NAME)
|
||||
if(NOT ANDROID)
|
||||
install(CODE "
|
||||
execute_process(COMMAND ${CMAKE_COMMAND} -E create_symlink
|
||||
- \"libSDL2-2.0.${SOEXT}\" \"libSDL2.${SOEXT}\")")
|
||||
- install(FILES ${SDL2_BINARY_DIR}/libSDL2.${SOEXT} DESTINATION "lib${LIB_SUFFIX}")
|
||||
+ \"lib${SONAME}${SOPOSTFIX}${SOEXT}\" \"libSDL2${SOPOSTFIX}${SOEXT}\")"
|
||||
+ WORKING_DIR "${SDL2_BINARY_DIR}")
|
||||
+ install(FILES ${SDL2_BINARY_DIR}/libSDL2${SOPOSTFIX}${SOEXT} DESTINATION "lib${LIB_SUFFIX}")
|
||||
endif()
|
||||
endif()
|
||||
if(FREEBSD)
|
||||
+537
-14
File diff suppressed because it is too large
Load Diff
@@ -1,2 +1,13 @@
|
||||
#include <SDL.h>
|
||||
#include <SDL_syswm.h>
|
||||
#include <SDL_vulkan.h>
|
||||
|
||||
/**
|
||||
* <div rustbindgen replaces="VkInstance"></div>
|
||||
*/
|
||||
typedef uintptr_t VkInstance_int;
|
||||
|
||||
/**
|
||||
* <div rustbindgen replaces="VkSurfaceKHR"></div>
|
||||
*/
|
||||
typedef uint64_t VkSurfaceKHR_int;
|
||||
|
||||
+37
-43
@@ -60,7 +60,6 @@ use std::ops::{Deref, DerefMut};
|
||||
use std::path::Path;
|
||||
use std::marker::PhantomData;
|
||||
use std::mem;
|
||||
use std::mem::transmute;
|
||||
use std::ptr;
|
||||
|
||||
use AudioSubsystem;
|
||||
@@ -209,12 +208,16 @@ pub enum AudioStatus {
|
||||
impl FromPrimitive for AudioStatus {
|
||||
fn from_i64(n: i64) -> Option<AudioStatus> {
|
||||
use self::AudioStatus::*;
|
||||
let n = n as u32;
|
||||
|
||||
Some( match unsafe { transmute::<u32, sys::SDL_AudioStatus>(n) } {
|
||||
sys::SDL_AudioStatus::SDL_AUDIO_STOPPED => Stopped,
|
||||
sys::SDL_AudioStatus::SDL_AUDIO_PLAYING => Playing,
|
||||
sys::SDL_AudioStatus::SDL_AUDIO_PAUSED => Paused,
|
||||
const STOPPED: i64 = sys::SDL_AudioStatus::SDL_AUDIO_STOPPED as i64;
|
||||
const PLAYING: i64 = sys::SDL_AudioStatus::SDL_AUDIO_PLAYING as i64;
|
||||
const PAUSED: i64 = sys::SDL_AudioStatus::SDL_AUDIO_PAUSED as i64;
|
||||
|
||||
Some(match n {
|
||||
STOPPED => Stopped,
|
||||
PLAYING => Playing,
|
||||
PAUSED => Paused,
|
||||
_ => return None,
|
||||
})
|
||||
}
|
||||
|
||||
@@ -373,13 +376,15 @@ extern "C" fn audio_callback_marshall<CB: AudioCallback>
|
||||
use std::slice::from_raw_parts_mut;
|
||||
use std::mem::size_of;
|
||||
unsafe {
|
||||
let cb_userdata: &mut CB = &mut *(userdata as *mut CB);
|
||||
let cb_userdata: &mut Option<CB> = &mut *(userdata as *mut _);
|
||||
let buf: &mut [CB::Channel] = from_raw_parts_mut(
|
||||
stream as *mut CB::Channel,
|
||||
len as usize / size_of::<CB::Channel>()
|
||||
);
|
||||
|
||||
cb_userdata.callback(buf);
|
||||
if let Some(cb) = cb_userdata {
|
||||
cb.callback(buf);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -394,14 +399,13 @@ pub struct AudioSpecDesired {
|
||||
}
|
||||
|
||||
impl AudioSpecDesired {
|
||||
fn convert_to_ll<CB, F, C, S>(freq: F, channels: C, samples: S, userdata: *mut CB) -> sys::SDL_AudioSpec
|
||||
fn convert_to_ll<CB, F, C, S>(freq: F, channels: C, samples: S, userdata: *mut Option<CB>) -> sys::SDL_AudioSpec
|
||||
where
|
||||
CB: AudioCallback,
|
||||
F: Into<Option<i32>>,
|
||||
C: Into<Option<u8>>,
|
||||
S: Into<Option<u16>>,
|
||||
{
|
||||
use std::mem::transmute;
|
||||
|
||||
let freq = freq.into();
|
||||
let channels = channels.into();
|
||||
@@ -413,22 +417,20 @@ impl AudioSpecDesired {
|
||||
|
||||
// A value of 0 means "fallback" or "default".
|
||||
|
||||
unsafe {
|
||||
sys::SDL_AudioSpec {
|
||||
freq: freq.unwrap_or(0),
|
||||
format: <CB::Channel as AudioFormatNum>::audio_format().to_ll(),
|
||||
channels: channels.unwrap_or(0),
|
||||
silence: 0,
|
||||
samples: samples.unwrap_or(0),
|
||||
padding: 0,
|
||||
size: 0,
|
||||
callback: Some(audio_callback_marshall::<CB>
|
||||
as extern "C" fn
|
||||
(arg1: *mut c_void,
|
||||
arg2: *mut uint8_t,
|
||||
arg3: c_int)),
|
||||
userdata: transmute(userdata)
|
||||
}
|
||||
sys::SDL_AudioSpec {
|
||||
freq: freq.unwrap_or(0),
|
||||
format: <CB::Channel as AudioFormatNum>::audio_format().to_ll(),
|
||||
channels: channels.unwrap_or(0),
|
||||
silence: 0,
|
||||
samples: samples.unwrap_or(0),
|
||||
padding: 0,
|
||||
size: 0,
|
||||
callback: Some(audio_callback_marshall::<CB>
|
||||
as extern "C" fn
|
||||
(arg1: *mut c_void,
|
||||
arg2: *mut uint8_t,
|
||||
arg3: c_int)),
|
||||
userdata: userdata as *mut _,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -596,7 +598,7 @@ pub struct AudioDevice<CB: AudioCallback> {
|
||||
device_id: AudioDeviceID,
|
||||
spec: AudioSpec,
|
||||
/// Store the callback to keep it alive for the entire duration of `AudioDevice`.
|
||||
userdata: Box<CB>
|
||||
userdata: Box<Option<CB>>
|
||||
}
|
||||
|
||||
impl<CB: AudioCallback> AudioDevice<CB> {
|
||||
@@ -607,14 +609,8 @@ impl<CB: AudioCallback> AudioDevice<CB> {
|
||||
D: Into<Option<&'a str>>,
|
||||
{
|
||||
|
||||
// SDL_OpenAudioDevice needs a userdata pointer, but we can't initialize the
|
||||
// callback without the obtained AudioSpec.
|
||||
// Create an uninitialized box that will be initialized after SDL_OpenAudioDevice.
|
||||
let userdata: *mut CB = unsafe {
|
||||
let b: Box<CB> = Box::new(mem::uninitialized());
|
||||
mem::transmute(b)
|
||||
};
|
||||
let desired = AudioSpecDesired::convert_to_ll(spec.freq, spec.channels, spec.samples, userdata);
|
||||
let mut userdata: Box<Option<CB>> = Box::new(None);
|
||||
let desired = AudioSpecDesired::convert_to_ll(spec.freq, spec.channels, spec.samples, &mut *userdata);
|
||||
|
||||
let mut obtained = unsafe { mem::uninitialized::<sys::SDL_AudioSpec>() };
|
||||
unsafe {
|
||||
@@ -636,10 +632,8 @@ impl<CB: AudioCallback> AudioDevice<CB> {
|
||||
id => {
|
||||
let device_id = AudioDeviceID::PlaybackDevice(id);
|
||||
let spec = AudioSpec::convert_from_ll(obtained);
|
||||
let mut userdata: Box<CB> = mem::transmute(userdata);
|
||||
|
||||
let garbage = mem::replace(&mut userdata as &mut CB, get_callback(spec));
|
||||
mem::forget(garbage);
|
||||
*userdata = Some(get_callback(spec));
|
||||
|
||||
Ok(AudioDevice {
|
||||
subsystem: a.clone(),
|
||||
@@ -713,7 +707,7 @@ impl<CB: AudioCallback> AudioDevice<CB> {
|
||||
/// but the callback data will be dropped.
|
||||
pub fn close_and_get_callback(self) -> CB {
|
||||
drop(self.device_id);
|
||||
*self.userdata
|
||||
self.userdata.expect("Missing callback")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -725,11 +719,11 @@ pub struct AudioDeviceLockGuard<'a, CB> where CB: AudioCallback, CB: 'a {
|
||||
|
||||
impl<'a, CB: AudioCallback> Deref for AudioDeviceLockGuard<'a, CB> {
|
||||
type Target = CB;
|
||||
fn deref(&self) -> &CB { &self.device.userdata }
|
||||
fn deref(&self) -> &CB { (*self.device.userdata).as_ref().expect("Missing callback") }
|
||||
}
|
||||
|
||||
impl<'a, CB: AudioCallback> DerefMut for AudioDeviceLockGuard<'a, CB> {
|
||||
fn deref_mut(&mut self) -> &mut CB { &mut self.device.userdata }
|
||||
fn deref_mut(&mut self) -> &mut CB { (*self.device.userdata).as_mut().expect("Missing callback") }
|
||||
}
|
||||
|
||||
impl<'a, CB: AudioCallback> Drop for AudioDeviceLockGuard<'a, CB> {
|
||||
@@ -829,13 +823,13 @@ mod test {
|
||||
assert!(cvt.is_conversion_needed());
|
||||
|
||||
// since we're going from mono to stereo, our capacity must be at least twice the original (255) vec size
|
||||
assert!(cvt.capacity(255) > 255*2, "capacity must be able to hold the converted audio sample");
|
||||
assert!(cvt.capacity(255) >= 255*2, "capacity must be able to hold the converted audio sample");
|
||||
|
||||
let new_buffer = cvt.convert(buffer);
|
||||
assert_eq!(new_buffer.len(), new_buffer_expected.len(), "capacity must be exactly equal to twice the original vec size");
|
||||
|
||||
// // this has been commented, see https://discourse.libsdl.org/t/change-of-behavior-in-audiocvt-sdl-convertaudio-from-2-0-5-to-2-0-6/24682
|
||||
// // to maybe re-enable it someday
|
||||
// // to maybe re-enable it someday
|
||||
// assert_eq!(new_buffer, new_buffer_expected);
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -3,7 +3,7 @@ use std::fmt;
|
||||
|
||||
/// A given integer was so big that its representation as a C integer would be
|
||||
/// negative.
|
||||
#[derive(Debug)]
|
||||
#[derive(Debug, Clone, PartialEq)]
|
||||
pub enum IntegerOrSdlError {
|
||||
IntegerOverflows(&'static str, u32),
|
||||
SdlError(String)
|
||||
|
||||
+32
-16
@@ -2,6 +2,7 @@ use libc::c_char;
|
||||
use std::error;
|
||||
use std::ffi::{CString, CStr, NulError};
|
||||
use std::fmt;
|
||||
use std::io;
|
||||
use std::path::Path;
|
||||
use rwops::RWops;
|
||||
|
||||
@@ -17,6 +18,7 @@ use sys;
|
||||
pub enum AddMappingError {
|
||||
InvalidMapping(NulError),
|
||||
InvalidFilePath(String),
|
||||
ReadError(String),
|
||||
SdlError(String),
|
||||
}
|
||||
|
||||
@@ -27,7 +29,8 @@ impl fmt::Display for AddMappingError {
|
||||
match *self {
|
||||
InvalidMapping(ref e) => write!(f, "Null error: {}", e),
|
||||
InvalidFilePath(ref value) => write!(f, "Invalid file path ({})", value),
|
||||
SdlError(ref e) => write!(f, "SDL error: {}", e)
|
||||
ReadError(ref e) => write!(f, "Read error: {}", e),
|
||||
SdlError(ref e) => write!(f, "SDL error: {}", e),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -39,6 +42,7 @@ impl error::Error for AddMappingError {
|
||||
match *self {
|
||||
InvalidMapping(_) => "invalid mapping",
|
||||
InvalidFilePath(_) => "invalid file path",
|
||||
ReadError(_) => "read error",
|
||||
SdlError(ref e) => e,
|
||||
}
|
||||
}
|
||||
@@ -110,7 +114,7 @@ impl GameControllerSubsystem {
|
||||
== sys::SDL_ENABLE as i32 }
|
||||
}
|
||||
|
||||
/// Add a new mapping from a mapping string
|
||||
/// Add a new controller input mapping from a mapping string.
|
||||
pub fn add_mapping(&self, mapping: &str)
|
||||
-> Result<MappingStatus, AddMappingError> {
|
||||
use self::AddMappingError::*;
|
||||
@@ -128,24 +132,36 @@ impl GameControllerSubsystem {
|
||||
}
|
||||
}
|
||||
|
||||
/// Load mappings from a file
|
||||
pub fn load_mappings<P: AsRef<Path>>(&self, path: P)
|
||||
-> Result<i32, AddMappingError> {
|
||||
/// Load controller input mappings from a file.
|
||||
pub fn load_mappings<P: AsRef<Path>>(&self, path: P) -> Result<i32, AddMappingError> {
|
||||
use self::AddMappingError::*;
|
||||
|
||||
let file = match RWops::from_file(path, "r") {
|
||||
Ok(f) => f,
|
||||
Err(s) => return Err(InvalidFilePath(s))
|
||||
};
|
||||
|
||||
let result = unsafe { sys::SDL_GameControllerAddMappingsFromRW(file.raw(), 0) };
|
||||
|
||||
match result {
|
||||
-1 => Err(SdlError(get_error())),
|
||||
_ => Ok(result)
|
||||
}
|
||||
let rw = RWops::from_file(path, "r").map_err(InvalidFilePath)?;
|
||||
self.load_mappings_from_rw(rw)
|
||||
}
|
||||
|
||||
/// Load controller input mappings from a [`Read`](std::io::Read) object.
|
||||
pub fn load_mappings_from_read<R: io::Read>(
|
||||
&self,
|
||||
read: &mut R,
|
||||
) -> Result<i32, AddMappingError> {
|
||||
use self::AddMappingError::*;
|
||||
|
||||
let mut buffer = Vec::with_capacity(1024);
|
||||
let rw = RWops::from_read(read, &mut buffer).map_err(ReadError)?;
|
||||
self.load_mappings_from_rw(rw)
|
||||
}
|
||||
|
||||
/// Load controller input mappings from an SDL [`RWops`] object.
|
||||
pub fn load_mappings_from_rw<'a>(&self, rw: RWops<'a>) -> Result<i32, AddMappingError> {
|
||||
use self::AddMappingError::*;
|
||||
|
||||
let result = unsafe { sys::SDL_GameControllerAddMappingsFromRW(rw.raw(), 0) };
|
||||
match result {
|
||||
-1 => Err(SdlError(get_error())),
|
||||
_ => Ok(result),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn mapping_for_guid(&self, guid: joystick::Guid) -> Result<String, String> {
|
||||
let c_str = unsafe { sys::SDL_GameControllerMappingForGUID(guid.raw()) };
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
//! # Getting started
|
||||
//!
|
||||
//! ```rust,no_run
|
||||
//! extern crate sdl2;
|
||||
//!
|
||||
//! use sdl2::pixels::Color;
|
||||
//! use sdl2::event::Event;
|
||||
//! use sdl2::keyboard::Keycode;
|
||||
|
||||
+92
-1
@@ -1,4 +1,4 @@
|
||||
use libc::{c_int, c_float, uint32_t, c_char};
|
||||
use libc::{c_int, c_uint, c_float, uint32_t, c_char};
|
||||
use std::ffi::{CStr, CString, NulError};
|
||||
use std::{mem, ptr, fmt};
|
||||
use std::rc::Rc;
|
||||
@@ -18,6 +18,8 @@ use get_error;
|
||||
|
||||
use sys;
|
||||
|
||||
pub use sys::{VkInstance, VkSurfaceKHR};
|
||||
|
||||
|
||||
pub struct WindowSurfaceRef<'a>(&'a mut SurfaceRef, &'a Window);
|
||||
|
||||
@@ -807,6 +809,61 @@ impl VideoSubsystem {
|
||||
mem::transmute(interval)
|
||||
}
|
||||
}
|
||||
|
||||
/// Loads the default Vulkan library.
|
||||
///
|
||||
/// This should be done after initializing the video driver, but before creating any Vulkan windows.
|
||||
/// If no Vulkan library is loaded, the default library will be loaded upon creation of the first Vulkan window.
|
||||
///
|
||||
/// If a different library is already loaded, this function will return an error.
|
||||
pub fn vulkan_load_library_default(&self) -> Result<(), String> {
|
||||
unsafe {
|
||||
if sys::SDL_Vulkan_LoadLibrary(ptr::null()) == 0 {
|
||||
Ok(())
|
||||
} else {
|
||||
Err(get_error())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Loads the Vulkan library using a platform-dependent Vulkan library name (usually a file path).
|
||||
///
|
||||
/// This should be done after initializing the video driver, but before creating any Vulkan windows.
|
||||
/// If no Vulkan library is loaded, the default library will be loaded upon creation of the first Vulkan window.
|
||||
///
|
||||
/// If a different library is already loaded, this function will return an error.
|
||||
pub fn vulkan_load_library<P: AsRef<::std::path::Path>>(&self, path: P) -> Result<(), String> {
|
||||
unsafe {
|
||||
// TODO: use OsStr::to_cstring() once it's stable
|
||||
let path = CString::new(path.as_ref().to_str().unwrap()).unwrap();
|
||||
if sys::SDL_Vulkan_LoadLibrary(path.as_ptr() as *const c_char) == 0 {
|
||||
Ok(())
|
||||
} else {
|
||||
Err(get_error())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Unloads the current Vulkan library.
|
||||
///
|
||||
/// To completely unload the library, this should be called for every successful load of the
|
||||
/// Vulkan library.
|
||||
pub fn vulkan_unload_library(&self) {
|
||||
unsafe { sys::SDL_Vulkan_UnloadLibrary(); }
|
||||
}
|
||||
|
||||
/// Gets the pointer to the
|
||||
/// [`vkGetInstanceProcAddr`](https://www.khronos.org/registry/vulkan/specs/1.1-extensions/man/html/vkGetInstanceProcAddr.html)
|
||||
/// Vulkan function. This function can be called to retrieve the address of other Vulkan
|
||||
/// functions.
|
||||
pub fn vulkan_get_proc_address_function(&self) -> Result<*const (), String> {
|
||||
let result = unsafe { sys::SDL_Vulkan_GetVkGetInstanceProcAddr() as *const () };
|
||||
if result.is_null() {
|
||||
Err(get_error())
|
||||
} else {
|
||||
Ok(result)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
@@ -1070,6 +1127,33 @@ impl Window {
|
||||
unsafe { sys::SDL_GL_SwapWindow(self.context.raw) }
|
||||
}
|
||||
|
||||
/// Get the names of the Vulkan instance extensions needed to create a surface with `vulkan_create_surface`.
|
||||
pub fn vulkan_instance_extensions(&self) -> Result<Vec<&'static str>, String> {
|
||||
let mut count: c_uint = 0;
|
||||
if unsafe { sys::SDL_Vulkan_GetInstanceExtensions(self.context.raw, &mut count, ptr::null_mut()) } == sys::SDL_bool::SDL_FALSE {
|
||||
return Err(get_error());
|
||||
}
|
||||
let mut names: Vec<*const c_char> = vec![ptr::null(); count as usize];
|
||||
if unsafe { sys::SDL_Vulkan_GetInstanceExtensions(self.context.raw, &mut count, names.as_mut_ptr()) } == sys::SDL_bool::SDL_FALSE {
|
||||
return Err(get_error());
|
||||
}
|
||||
Ok(names.iter().map(|&val| unsafe { CStr::from_ptr(val) }.to_str().unwrap()).collect())
|
||||
}
|
||||
|
||||
/// Create a Vulkan rendering surface for a window.
|
||||
///
|
||||
/// The `VkInstance` must be created using a prior call to the
|
||||
/// [`vkCreateInstance`](https://www.khronos.org/registry/vulkan/specs/1.1-extensions/man/html/vkCreateInstance.html)
|
||||
/// function in the Vulkan library.
|
||||
pub fn vulkan_create_surface(&self, instance: VkInstance) -> Result<VkSurfaceKHR, String> {
|
||||
let mut surface: VkSurfaceKHR = 0;
|
||||
if unsafe { sys::SDL_Vulkan_CreateSurface(self.context.raw, instance, &mut surface) } == sys::SDL_bool::SDL_FALSE {
|
||||
Err(get_error())
|
||||
} else {
|
||||
Ok(surface)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn display_index(&self) -> Result<i32, String> {
|
||||
let result = unsafe { sys::SDL_GetWindowDisplayIndex(self.context.raw) };
|
||||
if result < 0 {
|
||||
@@ -1205,6 +1289,13 @@ impl Window {
|
||||
(w as u32, h as u32)
|
||||
}
|
||||
|
||||
pub fn vulkan_drawable_size(&self) -> (u32, u32) {
|
||||
let mut w: c_int = 0;
|
||||
let mut h: c_int = 0;
|
||||
unsafe { sys::SDL_Vulkan_GetDrawableSize(self.context.raw, &mut w, &mut h) };
|
||||
(w as u32, h as u32)
|
||||
}
|
||||
|
||||
pub fn set_minimum_size(&mut self, width: u32, height: u32)
|
||||
-> Result<(), IntegerOrSdlError> {
|
||||
let w = try!(validate_int(width, "width"));
|
||||
|
||||
Reference in New Issue
Block a user