vibtify 0.1.1

A Rust crate for high-level interaction with a gamepad
Documentation
use crate::bit::get_bit;

const ACTIVE_BLOCK_1: usize = 0x23;
const DATA_BLOCK_A_1: usize = 0x24;
const DATA_BLOCK_B_1: usize = 0x25;
const DATA_BLOCK_C_1: usize = 0x26;

const ACTIVE_BLOCK_2: usize = 0x27;
const DATA_BLOCK_A_2: usize = 0x28;
const DATA_BLOCK_B_2: usize = 0x29;
const DATA_BLOCK_C_2: usize = 0x2a;

/// A structure that stores a snapshot of the touchpad state.
#[derive(Debug)]
pub struct TPadState {
    is_touched_1: bool,
    xy_1: Option<(u16, u16)>,

    is_touched_2: bool,
    xy_2: Option<(u16, u16)>,

    is_pressed: bool
}

impl TPadState {
    pub(crate) fn from_buf(buf: &[u8; 64]) -> Self {
        let active_1 = buf[ACTIVE_BLOCK_1] < 0x80;

        let xy_1 = if active_1 {
            Some((
                decode_touch_x(false, buf),
                decode_touch_y(false, buf)
            ))
        } else {
            None
        };

        let active_2 = buf[ACTIVE_BLOCK_2] < 0x80;

        let xy_2 = if active_2 {
            Some((
                decode_touch_x(true, buf),
                decode_touch_y(true, buf)
            ))
        } else {
            None
        };

        let is_pressed = get_bit(buf[0x07], 1) == 1;

        Self {
            is_touched_1: active_1,
            xy_1,

            is_touched_2: active_2,
            xy_2,

            is_pressed
        }
    }
}

fn decode_touch_x(is_2: bool, buf: &[u8]) -> u16 {
    let a = if is_2 { DATA_BLOCK_A_2 } else { DATA_BLOCK_A_1 };
    let b = if is_2 { DATA_BLOCK_B_2 } else { DATA_BLOCK_B_1 };

    let block_a = u16::from(buf[a]);
    let block_b = u16::from(buf[b]);

    ((block_b & 0x0f) << 8) | block_a
}

fn decode_touch_y(is_2: bool, buf: &[u8]) -> u16 {
    let b = if is_2 { DATA_BLOCK_B_2 } else { DATA_BLOCK_B_1 };
    let c = if is_2 { DATA_BLOCK_C_2 } else { DATA_BLOCK_C_1 };

    let block_b = u16::from(buf[b]);
    let block_c = u16::from(buf[c]);

    (block_c << 4) | ((block_b & 0xf0) >> 4)
}