Modified controller inputs to work like keys

This commit is contained in:
transistor 2021-12-04 14:41:27 -08:00
parent 8ced62cca0
commit 73c5b26e86
7 changed files with 87 additions and 49 deletions

View File

@ -0,0 +1,19 @@
use minifb::Key as MiniKey;
use moa::host::controllers::ControllerEvent;
pub fn map_controller_a(key: MiniKey, state: bool) -> Option<ControllerEvent> {
match key {
MiniKey::A => { Some(ControllerEvent::ButtonA(state)) },
MiniKey::B => { Some(ControllerEvent::ButtonB(state)) },
MiniKey::C => { Some(ControllerEvent::ButtonC(state)) },
MiniKey::Up => { Some(ControllerEvent::DpadUp(state)) },
MiniKey::Down => { Some(ControllerEvent::DpadDown(state)) },
MiniKey::Left => { Some(ControllerEvent::DpadLeft(state)) },
MiniKey::Right => { Some(ControllerEvent::DpadRight(state)) },
MiniKey::Enter => { Some(ControllerEvent::Start(state)) },
MiniKey::M => { Some(ControllerEvent::Mode(state)) },
_ => None,
}
}

View File

@ -9,10 +9,13 @@ use clap::{App, ArgMatches};
use moa::error::Error;
use moa::system::System;
use moa::host::traits::{Host, ControllerUpdater, KeyboardUpdater, WindowUpdater};
use moa::host::controller::{ControllerDevice, Controller};
use moa::host::controllers::{ControllerDevice, ControllerEvent};
mod keys;
mod controllers;
use crate::keys::map_key;
use crate::controllers::map_controller_a;
const WIDTH: u32 = 320;
@ -132,6 +135,7 @@ impl Host for MiniFrontendBuilder {
pub struct MiniFrontend {
pub buffer: Vec<u32>,
pub modifiers: u16,
pub window: Option<Box<dyn WindowUpdater>>,
pub controller: Option<Box<dyn ControllerUpdater>>,
pub keyboard: Option<Box<dyn KeyboardUpdater>>,
@ -141,6 +145,7 @@ impl MiniFrontend {
pub fn new(window: Option<Box<dyn WindowUpdater>>, controller: Option<Box<dyn ControllerUpdater>>, keyboard: Option<Box<dyn KeyboardUpdater>>) -> Self {
Self {
buffer: vec![0; (WIDTH * HEIGHT) as usize],
modifiers: 0,
window,
controller,
keyboard,
@ -185,35 +190,19 @@ impl MiniFrontend {
}
if let Some(keys) = window.get_keys_pressed(minifb::KeyRepeat::Yes) {
let mut modifiers: u16 = 0x0000;
for key in keys {
if let Some(updater) = self.keyboard.as_mut() {
updater.update_keyboard(map_key(key), true);
}
self.check_key(key, true);
// Process special keys
match key {
Key::A => { modifiers |= 0x0040; },
Key::B => { modifiers |= 0x0010; },
Key::C => { modifiers |= 0x0020; },
Key::Up => { modifiers |= 0x0001; },
Key::Down => { modifiers |= 0x0002; },
Key::Left => { modifiers |= 0x0004; },
Key::Right => { modifiers |= 0x0008; },
Key::Enter => { modifiers |= 0x0080; },
Key::M => { modifiers |= 0x0100; },
Key::D => { system.as_ref().map(|s| s.enable_debugging()); },
_ => { },
}
}
if let Some(updater) = self.controller.as_mut() {
let data = Controller { bits: modifiers };
updater.update_controller(data);
}
}
if let Some(keys) = window.get_keys_released() {
for key in keys {
if let Some(updater) = self.keyboard.as_mut() {
updater.update_keyboard(map_key(key), false);
}
self.check_key(key, false);
}
}
@ -223,5 +212,17 @@ impl MiniFrontend {
}
}
}
fn check_key(&mut self, key: Key, state: bool) {
if let Some(updater) = self.keyboard.as_mut() {
updater.update_keyboard(map_key(key), state);
}
if let Some(updater) = self.controller.as_mut() {
if let Some(event) = map_controller_a(key, state) {
updater.update_controller(event);
}
}
}
}

View File

@ -1,19 +0,0 @@
#[derive(Copy, Clone, Debug, PartialEq)]
pub enum ControllerDevice {
A,
B,
C,
D,
}
pub struct Controller {
//pub dpad_up: bool,
//pub dpad_down: bool,
//pub dpad_left: bool,
//pub dpad_right: bool,
// TODO this is temporary until I actually implement this properly
pub bits: u16,
}

25
src/host/controllers.rs Normal file
View File

@ -0,0 +1,25 @@
#[derive(Copy, Clone, Debug, PartialEq)]
pub enum ControllerDevice {
A,
B,
C,
D,
}
#[derive(Copy, Clone, Debug, PartialEq)]
pub enum ControllerEvent {
DpadUp(bool),
DpadDown(bool),
DpadLeft(bool),
DpadRight(bool),
ButtonA(bool),
ButtonB(bool),
ButtonC(bool),
ButtonX(bool),
ButtonY(bool),
ButtonZ(bool),
Start(bool),
Mode(bool),
}

View File

@ -6,5 +6,5 @@ pub mod tty;
pub mod gfx;
pub mod keys;
pub mod controller;
pub mod controllers;

View File

@ -3,7 +3,7 @@ use std::sync::{Arc, Mutex, MutexGuard};
use crate::error::Error;
use crate::host::keys::Key;
use crate::host::controller::{ControllerDevice, Controller};
use crate::host::controllers::{ControllerDevice, ControllerEvent};
pub trait Host {
//fn create_pty(&self) -> Result<Box<dyn Tty>, Error>;
@ -24,7 +24,7 @@ pub trait WindowUpdater: Send {
}
pub trait ControllerUpdater: Send {
fn update_controller(&mut self, data: Controller);
fn update_controller(&mut self, event: ControllerEvent);
}
pub trait KeyboardUpdater: Send {

View File

@ -1,7 +1,7 @@
use crate::error::Error;
use crate::devices::{Address, Addressable, Transmutable};
use crate::host::controller::{ControllerDevice, Controller};
use crate::host::controllers::{ControllerDevice, ControllerEvent};
use crate::host::traits::{Host, ControllerUpdater, SharedData};
@ -78,11 +78,23 @@ impl GenesisControllerPort {
pub struct GenesisControllerUpdater(SharedData<u16>, SharedData<bool>);
impl ControllerUpdater for GenesisControllerUpdater {
fn update_controller(&mut self, data: Controller) {
//let modifiers = if data.bits == 0 { 0xFFFF } else { data.bits };
let modifiers = !data.bits;
self.0.set(modifiers);
if data.bits != 0 {
fn update_controller(&mut self, event: ControllerEvent) {
let (mask, state) = match event {
ControllerEvent::ButtonA(state) => (0x0040, state),
ControllerEvent::ButtonB(state) => (0x0010, state),
ControllerEvent::ButtonC(state) => (0x0020, state),
ControllerEvent::DpadUp(state) => (0x0001, state),
ControllerEvent::DpadDown(state) => (0x0002, state),
ControllerEvent::DpadLeft(state) => (0x0004, state),
ControllerEvent::DpadRight(state) => (0x0008, state),
ControllerEvent::Start(state) => (0x0080, state),
ControllerEvent::Mode(state) => (0x0100, state),
_ => (0x0000, false),
};
let buttons = (self.0.get() & !mask) | (if !state { mask } else { 0 });
self.0.set(buttons);
if buttons != 0 {
self.1.set(true);
}
}