Skip to content

Commit

Permalink
Generate all steps internally; return pointer to array
Browse files Browse the repository at this point in the history
  • Loading branch information
VirxEC committed Jul 6, 2024
1 parent 7c0fafe commit ab7c220
Show file tree
Hide file tree
Showing 3 changed files with 32 additions and 12 deletions.
2 changes: 1 addition & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "rl_ball_sym_dll"
version = "0.1.4"
version = "0.1.5"
edition = "2021"

[lib]
Expand Down
40 changes: 30 additions & 10 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,6 @@ pub extern "C" fn load_standard_throwback() {
}

#[repr(C)]
#[derive(Default)]
pub struct Vec3 {
x: f32,
y: f32,
Expand All @@ -76,7 +75,6 @@ impl From<Vec3A> for Vec3 {
}

#[repr(C)]
#[derive(Default)]
pub struct BallSlice {
pub time: f32,
pub location: Vec3,
Expand Down Expand Up @@ -115,31 +113,53 @@ pub extern "C" fn reset_heatseeker_target() {
}

#[no_mangle]
pub extern "C" fn step(current_ball: BallSlice) -> BallSlice {
pub extern "C" fn step(current_ball: BallSlice, ticks: u16) -> *mut BallSlice {
let state = GAME_AND_BALL.read().unwrap();

let Some(game) = state.game.as_ref() else {
// Don't use println!() to avoid bringing in the `fmt` module
let out = stdout();
let mut handle = out.lock();
handle.write_all(b"Warning: No game loaded\n").unwrap();
handle.flush().unwrap();

return BallSlice::default();
return std::ptr::null_mut();
};

let mut ball = state.ball;
let mut balls = Vec::with_capacity(ticks as usize);

ball.update(
current_ball.time,
current_ball.location.into(),
current_ball.linear_velocity.into(),
current_ball.angular_velocity.into(),
);

if state.heatseeker {
ball.step_heatseeker(game, DT);
} else {
ball.step(game, DT);
for _ in 0..ticks {
if state.heatseeker {
ball.step_heatseeker(game, DT);
} else {
ball.step(game, DT);
}

balls.push(ball.into());
}

ball.into()
// Remove excess capacity so the length is exactly `ticks`
balls.shrink_to_fit();
// Turn into pointer
let ptr = balls.as_mut_ptr();
// Prevent the memory from being deallocated
std::mem::forget(balls);

ptr
}

/// # Safety
///
/// Ensure that the pointer is valid and that the memory it points to is not deallocated.
#[no_mangle]
pub unsafe extern "C" fn free_ball_slices(ptr: *mut BallSlice, size: u16) {
let length = size as usize;
Vec::from_raw_parts(ptr, length, length);
}

0 comments on commit ab7c220

Please sign in to comment.