master
Vinícius W 8 months ago
commit e369a9f20b

@ -0,0 +1,3 @@
[target.x86_64-unknown-linux-gnu]
linker = "clang"
rustflags = ["-Zshare-generics=y", "-C", "link-arg=-fuse-ld=/usr/bin/mold"]

1
.gitignore vendored

@ -0,0 +1 @@
/target

4271
Cargo.lock generated

File diff suppressed because it is too large Load Diff

@ -0,0 +1,73 @@
[package]
name = "bevy_android"
authors = ["Vynwg"]
version = "0.1.0"
edition = "2021"
[package.metadata.android]
package = "com.vynwg.bevyandroid"
apk_name = "bevyandroid"
assets = "./assets"
strip = "strip"
build_targets = ["aarch64-linux-android", "armv7-linux-androideabi"]
[package.metadata.android.sdk]
target_sdk_version = 31
[package.metadata.android.application]
label = "Bevy Android"
[package.metadata.android.application.activity]
orientation = "landscape"
[lib]
name = "bevy_android"
crate-type = ["staticlib", "cdylib"]
[profile.dev]
opt-level = 1
[profile.dev.package."*"]
opt-level = 3
[profile.release]
codegen-units = 1
lto = "thin"
[profile.wasm-release]
inherits = "release"
opt-level = "s"
strip = "debuginfo"
[dependencies]
android_sensor-sys = "0.1.4"
android_looper-sys = "0.1"
[dependencies.log]
version = "*"
features = ["max_level_trace", "release_max_level_debug"]
[dependencies.bevy]
git = "https://github.com/bevyengine/bevy"
rev = "3892adc"
default-features = false
features = [
"png",
"bevy_ui",
"async-io",
"animation",
"bevy_text",
"serialize",
"bevy_asset",
"bevy_audio",
"bevy_scene",
"bevy_winit",
"bevy_gizmos",
"bevy_render",
"bevy_sprite",
"default_font",
"multi_threaded",
"bevy_core_pipeline",
"android_shared_stdcxx"
]

Binary file not shown.

@ -0,0 +1,2 @@
[toolchain]
channel = "nightly"

@ -0,0 +1,68 @@
mod util;
mod sensor;
use bevy::prelude::*;
use bevy::sprite::{MaterialMesh2dBundle, Mesh2dHandle, Wireframe2dConfig, Wireframe2dPlugin};
use bevy::window::WindowMode;
use bevy::color::palettes::css::*;
use bevy::diagnostic::{DiagnosticsStore, FrameTimeDiagnosticsPlugin};
use crate::sensor::SensorPlugin;
use crate::sensor::MagneticEvent;
#[derive(Component)]
struct TextChanges;
fn setup(
mut commands: Commands,
mut meshes: ResMut<Assets<Mesh>>,
mut materials: ResMut<Assets<ColorMaterial>>
) {
commands.spawn(Camera2dBundle::default());
commands.spawn(
TextBundle::from_sections([
TextSection::new("FODAAAAAAA", TextStyle::default())
])
.with_style(Style {
position_type: PositionType::Absolute,
top: Val::Px(0.0),
left: Val::Px(0.0),
..default()
})
);
}
fn change_text(mut events: EventReader<MagneticEvent>, mut query: Query<&mut Text, With<TextChanges>>) {
let (mut x, mut y, mut z) = (0.0, 0.0, 0.0);
for event in events.read() {
x = event.x;
y = event.y;
z = event.z;
}
for mut text in &mut query {
text.sections[0].value = format!("x: {} y: {} z: {}", x, y, z);
}
}
#[bevy_main]
fn main() {
let mut app = App::new();
app
.add_plugins(DefaultPlugins.set(WindowPlugin {
primary_window: Some(Window {
resizable: false,
mode: WindowMode::BorderlessFullscreen(MonitorSelection::Primary),
recognize_rotation_gesture: true,
..default()
}),
..default()
}))
.add_plugins(SensorPlugin)
.add_systems(Startup, setup)
.add_systems(Update, change_text)
.run();
}

@ -0,0 +1,103 @@
use std::ptr;
use bevy::prelude::*;
use crate::util::is_valid;
use android_looper_sys::{
ALooper_prepare,
ALooper_pollOnce
};
use android_sensor_sys::{
SensorType,
ASensorEvent,
ASensorEventQueue,
ASensorManager_getInstance,
ASensorEventQueue_getEvents,
ASensorEventQueue_hasEvents,
ASensorEventQueue_enableSensor,
ASensorEventQueue_setEventRate,
ASensorManager_createEventQueue,
ASensorManager_getDefaultSensor,
};
#[derive(Event)]
pub struct MagneticEvent {
pub x: f32,
pub y: f32,
pub z: f32
}
/* LOOPER IDs
1 is used for android_activity's main thread
2 is used for it's input handling thread
3 is supposed to be used for something too, idk
4 should be safe right? TODO: remove the stupid line at android_activity/native_activity/mod.rs:301, using 2 for now
*/
const ALOOPER_IDENTIFIER: i32 = 2;
const SENSOR_EVENT_RATE: i32 = 100000;
const ALOOPER_PREPARE_ALLOW_NON_CALLBACKS: i32 = 1;
const SENSOR_TYPE: i32 = SensorType::MagneticField as i32;
fn poll_events(queue: NonSend<*mut ASensorEventQueue>, mut events: EventWriter<MagneticEvent>) {
let queue = *queue;
let res = unsafe { ALooper_pollOnce(0, ptr::null_mut(), ptr::null_mut(), ptr::null_mut()) };
match res {
-3 => return,
-4 => panic!("Error polling once"),
ALOOPER_IDENTIFIER | -1 | -2 => {},
_ => return debug!("Polled from another Looper: {}", res)
}
if unsafe { ASensorEventQueue_hasEvents(queue) } == 0 { return }
let mut event = ASensorEvent::default();
while unsafe { ASensorEventQueue_getEvents(queue, &mut event, 1) } > 0 {
let read = unsafe {
let m = event.magnetic();
if !is_valid(m) { continue; }
m.read()
};
let result = unsafe {
let v = read.v();
if !is_valid(v) { continue; }
v.read()
};
events.send(MagneticEvent { x: result[0], y: result[1], z: result[2] });
}
}
pub struct SensorPlugin;
impl Plugin for SensorPlugin {
fn build(&self, app: &mut App) {
let manager = unsafe { ASensorManager_getInstance() };
let sensor = unsafe { ASensorManager_getDefaultSensor(manager, SENSOR_TYPE) };
let looper = unsafe { ALooper_prepare(ALOOPER_PREPARE_ALLOW_NON_CALLBACKS) };
let queue = unsafe { ASensorManager_createEventQueue(manager, looper, ALOOPER_IDENTIFIER, None, ptr::null_mut()) };
let res = unsafe { ASensorEventQueue_enableSensor(queue, sensor) };
if res < 0 {
panic!("Couldn't enable sensor {}, error code: {}", SENSOR_TYPE, res);
} else { debug!("Enabled sensor {}", SENSOR_TYPE); }
let res = unsafe { ASensorEventQueue_setEventRate(queue, sensor, SENSOR_EVENT_RATE) };
if res < 0 {
panic!("Couldn't set sensor's event rate, error code: {}", res);
} else { debug!("Set sensor event rate to {}", SENSOR_EVENT_RATE); }
app.add_event::<MagneticEvent>()
.insert_non_send_resource(queue)
.add_systems(Update, poll_events);
}
}

@ -0,0 +1,11 @@
use bevy::prelude::*;
pub fn is_valid<T>(ptr: *const T) -> bool {
if !ptr.is_null() {
debug!("Got a null pointer {:?}", ptr)
}
if !ptr.is_aligned() {
debug!("Got an unaligned pointer {:?}", ptr)
}
true
}
Loading…
Cancel
Save