mirror of
https://github.com/italicsjenga/gba.git
synced 2024-12-23 10:51:30 +11:00
arctan and arctan2
This commit is contained in:
parent
2ecf62e06e
commit
e38ddee38b
|
@ -3,6 +3,12 @@
|
|||
* **0.9.2:**
|
||||
* Adds support for more BIOS functions, though not all functions are as
|
||||
clearly documented as I'd like.
|
||||
* Made much more of the `Fixed` type const friendly. Most ops now have an
|
||||
inherent method that is `const fn` as well as implementing the `core::ops`
|
||||
trait (the trait fn just calls the inherent fn). This means that you can't
|
||||
do `x + y` in a const context, but you can do `x.add(y)`. This is not the
|
||||
best system, but until const trait impls are stable this is the best middle
|
||||
ground.
|
||||
* **0.9.1:**
|
||||
* Adds some randomization support directly into the crate.
|
||||
* Added more methods to the `Fixed` type.
|
||||
|
|
66
src/bios.rs
66
src/bios.rs
|
@ -8,11 +8,31 @@
|
|||
//! of the function ends up inlined). Despite this higher cost, some bios
|
||||
//! functions are useful enough to justify the overhead.
|
||||
|
||||
use crate::interrupts::IrqBits;
|
||||
use crate::{fixed::i16fx14, interrupts::IrqBits};
|
||||
|
||||
// Note(Lokathor): All `swi` calls will preserve the flags. You should generally
|
||||
// not use any other inline-asm options with `swi` calls.
|
||||
|
||||
/// `0x00`: Software Reset.
|
||||
///
|
||||
/// This clears the BIOS portion of IWRAM (the top `0x200` bytes), resets the
|
||||
/// SVC, IRQ, and SYS stack pointers to their defaults, then performs a `bx r14`
|
||||
/// to go to an address based on what's written to the byte at `0x0300_7FFA`:
|
||||
/// * zero: `0x0800_0000` (ROM)
|
||||
/// * non-zero: `0x0200_0000` (IWRAM).
|
||||
///
|
||||
/// (Note: the target address is determined *before* clearing the top of IWRAM.)
|
||||
#[inline]
|
||||
#[instruction_set(arm::t32)]
|
||||
pub fn SoftReset() -> ! {
|
||||
unsafe {
|
||||
core::arch::asm! {
|
||||
"swi #0x00",
|
||||
options(noreturn),
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/// `0x04`: Waits for a specific interrupt type(s) to happen.
|
||||
///
|
||||
/// Pauses the CPU until any of the interrupt types set in `target_irqs` to
|
||||
|
@ -62,6 +82,50 @@ pub fn VBlankIntrWait() {
|
|||
};
|
||||
}
|
||||
|
||||
/// `0x09`: Arc tangent.
|
||||
///
|
||||
/// * **Returns:** The output is in the range +/- `pi/2`, but accuracy is worse
|
||||
/// outside of +/- `pi/4`.
|
||||
#[inline]
|
||||
#[instruction_set(arm::t32)]
|
||||
pub fn ArcTan(theta: i16fx14) -> i16fx14 {
|
||||
let mut i = theta.into_raw();
|
||||
unsafe {
|
||||
core::arch::asm! {
|
||||
"swi #0x09",
|
||||
inout("r0") i,
|
||||
out("r1") _,
|
||||
out("r3") _,
|
||||
options(pure, nomem, preserves_flags),
|
||||
}
|
||||
};
|
||||
i16fx14::from_raw(i)
|
||||
}
|
||||
|
||||
/// `0x0A`: The "2-argument arctangent" ([atan2][wp-atan2]).
|
||||
///
|
||||
/// [wp-atan2]: https://en.wikipedia.org/wiki/Atan2
|
||||
///
|
||||
/// * **Returns:** The angle of the input vector, with `u16::MAX` being
|
||||
/// equivalent to `2pi`.
|
||||
#[inline]
|
||||
#[instruction_set(arm::t32)]
|
||||
pub fn ArcTan2(x: i16fx14, y: i16fx14) -> u16 {
|
||||
let x = x.into_raw();
|
||||
let y = y.into_raw();
|
||||
let output: u16;
|
||||
unsafe {
|
||||
core::arch::asm! {
|
||||
"swi #0x0A",
|
||||
inout("r0") x => output,
|
||||
inout("r1") y => _,
|
||||
out("r3") _,
|
||||
options(pure, nomem, preserves_flags),
|
||||
}
|
||||
};
|
||||
output
|
||||
}
|
||||
|
||||
/// Used to provide info to a call of the [`BitUnPack`] function.
|
||||
#[derive(Debug, Clone, Copy, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
||||
#[repr(C)]
|
||||
|
|
|
@ -6,6 +6,12 @@ use core::ops::*;
|
|||
#[allow(non_camel_case_types)]
|
||||
pub type i16fx8 = Fixed<i16, 8>;
|
||||
|
||||
/// `i16` with 14 bits of fixed-point fraction.
|
||||
///
|
||||
/// This is used by the [`ArcTan`] and [`ArcTan2`] BIOS functions.
|
||||
#[allow(non_camel_case_types)]
|
||||
pub type i16fx14 = Fixed<i16, 14>;
|
||||
|
||||
/// `i32` with 8 bits of fixed-point fraction.
|
||||
///
|
||||
/// This is used by the background reference point entries.
|
||||
|
|
Loading…
Reference in a new issue