Controls and collisions
This commit is contained in:
parent
23bb3e1153
commit
57a634d4ee
@ -1,7 +1,10 @@
|
||||
- improve collisions
|
||||
- controls (input)
|
||||
- clear lines
|
||||
- deadlocks
|
||||
- deadlocks?
|
||||
- fix arrow keys
|
||||
- better rng
|
||||
- keypress on start
|
||||
- enum and consts for interrupt index
|
||||
- fix asm loader
|
||||
- minimal interrupts
|
||||
- quick drop
|
||||
- document everything
|
||||
|
@ -38,6 +38,7 @@ lazy_static! {
|
||||
idt.divide_error.set_handler_fn(divide_handler);
|
||||
idt.double_fault.set_handler_fn(double_fault_handler);
|
||||
idt.interrupts[InterruptIndex::Timer.as_idx()].set_handler_fn(timer_handler);
|
||||
idt.interrupts[InterruptIndex::Keyboard.as_idx()].set_handler_fn(keyboard_handler);
|
||||
|
||||
idt
|
||||
};
|
||||
@ -64,6 +65,85 @@ extern "x86-interrupt" fn divide_handler(stack_frame: InterruptStackFrame) {
|
||||
println!("DIVIDE ERROR {:?}", stack_frame);
|
||||
}
|
||||
|
||||
unsafe fn inb(port: u32) -> u8 {
|
||||
let mut out;
|
||||
|
||||
asm!(
|
||||
"in al, dx",
|
||||
out("al") out,
|
||||
in("dx") port,
|
||||
);
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
enum InputKey {
|
||||
Left,
|
||||
Right,
|
||||
Up,
|
||||
Down,
|
||||
}
|
||||
|
||||
extern "x86-interrupt" fn keyboard_handler(stack_frame: InterruptStackFrame) {
|
||||
println!("KEYBOARD {:?}", stack_frame);
|
||||
|
||||
let scancode = unsafe { inb(0x60) };
|
||||
println!("{:x?}", scancode);
|
||||
|
||||
let key = match scancode {
|
||||
0x11 => Some(InputKey::Up),
|
||||
0x1E => Some(InputKey::Left),
|
||||
0x1F => Some(InputKey::Down),
|
||||
0x20 => Some(InputKey::Right),
|
||||
0xE0 => {
|
||||
let scancode = unsafe { inb(0x60) };
|
||||
println!("e {:x?}", scancode);
|
||||
None
|
||||
}
|
||||
_ => None,
|
||||
};
|
||||
|
||||
if let Some(fall) = &mut *FALLING.lock() {
|
||||
let board = BOARD.lock();
|
||||
let mut fall_test = fall.clone();
|
||||
|
||||
match key {
|
||||
Some(InputKey::Up) => {
|
||||
fall_test.rotate_cw();
|
||||
if board.tetromino_valid(&fall_test) {
|
||||
fall.rotate_cw()
|
||||
};
|
||||
}
|
||||
|
||||
Some(InputKey::Down) => {
|
||||
fall_test.rotate_ccw();
|
||||
if board.tetromino_valid(&fall_test) {
|
||||
fall.rotate_ccw()
|
||||
};
|
||||
}
|
||||
|
||||
Some(InputKey::Left) => {
|
||||
fall_test.translate(-1, 0);
|
||||
if board.tetromino_valid(&fall_test) {
|
||||
fall.translate(-1, 0);
|
||||
};
|
||||
}
|
||||
|
||||
Some(InputKey::Right) => {
|
||||
fall_test.translate(1, 0);
|
||||
if board.tetromino_valid(&fall_test) {
|
||||
fall.translate(1, 0);
|
||||
};
|
||||
}
|
||||
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
||||
PIC.lock().send_eoi(InterruptIndex::Keyboard.as_u8());
|
||||
}
|
||||
|
||||
extern "x86-interrupt" fn timer_handler(_stack_frame: InterruptStackFrame) {
|
||||
if !*RUN_TICKS.lock() {
|
||||
PIC.lock().send_eoi(InterruptIndex::Timer.as_u8());
|
||||
@ -86,7 +166,10 @@ extern "x86-interrupt" fn timer_handler(_stack_frame: InterruptStackFrame) {
|
||||
|
||||
if let Some(fall_inner) = fall.as_mut() {
|
||||
if t % 6 == 0 {
|
||||
if board.tetromino_free_below(fall_inner) {
|
||||
let mut fall_test = fall_inner.clone();
|
||||
fall_test.translate(0, 1);
|
||||
|
||||
if board.tetromino_valid(&fall_test) {
|
||||
fall_inner.translate(0, 1);
|
||||
} else {
|
||||
let mut x = None;
|
||||
|
@ -72,6 +72,7 @@ impl Direction {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct FallingTetromino {
|
||||
tetromino: Tetromino,
|
||||
direction: Direction,
|
||||
|
@ -39,9 +39,11 @@ impl TetrisBoard {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn tetromino_free_below(&self, tetromino: &FallingTetromino) -> bool {
|
||||
/// Returns `false` if the given tetromino intersects a filled cell
|
||||
/// or exits the board boundary
|
||||
pub fn tetromino_valid(&self, tetromino: &FallingTetromino) -> bool {
|
||||
for (x, y) in tetromino.tiles() {
|
||||
let cell = self.get_cell(x, y + 1);
|
||||
let cell = self.get_cell(x, y);
|
||||
if cell != Some(&TetrisCell::Empty) {
|
||||
return false;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user