mirror of
https://github.com/transistorfet/moa.git
synced 2024-11-25 15:33:08 +00:00
Renamed joystick to controller in host traits
This commit is contained in:
parent
b165e18fac
commit
9464e4c75a
@ -8,7 +8,8 @@ use clap::{App, ArgMatches};
|
||||
|
||||
use moa::error::Error;
|
||||
use moa::system::System;
|
||||
use moa::host::traits::{Host, JoystickDevice, JoystickUpdater, KeyboardUpdater, WindowUpdater};
|
||||
use moa::host::traits::{Host, ControllerUpdater, KeyboardUpdater, WindowUpdater};
|
||||
use moa::host::controller::{ControllerDevice, Controller};
|
||||
|
||||
mod keys;
|
||||
use crate::keys::map_key;
|
||||
@ -71,7 +72,7 @@ fn wait_until_initialized(frontend: Arc<Mutex<MiniFrontendBuilder>>) {
|
||||
|
||||
pub struct MiniFrontendBuilder {
|
||||
pub window: Option<Box<dyn WindowUpdater>>,
|
||||
pub joystick: Option<Box<dyn JoystickUpdater>>,
|
||||
pub controller: Option<Box<dyn ControllerUpdater>>,
|
||||
pub keyboard: Option<Box<dyn KeyboardUpdater>>,
|
||||
pub finalized: bool,
|
||||
}
|
||||
@ -80,7 +81,7 @@ impl MiniFrontendBuilder {
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
window: None,
|
||||
joystick: None,
|
||||
controller: None,
|
||||
keyboard: None,
|
||||
finalized: false,
|
||||
}
|
||||
@ -92,9 +93,9 @@ impl MiniFrontendBuilder {
|
||||
|
||||
pub fn build(&mut self) -> MiniFrontend {
|
||||
let window = std::mem::take(&mut self.window);
|
||||
let joystick = std::mem::take(&mut self.joystick);
|
||||
let controller = std::mem::take(&mut self.controller);
|
||||
let keyboard = std::mem::take(&mut self.keyboard);
|
||||
MiniFrontend::new(window, joystick, keyboard)
|
||||
MiniFrontend::new(window, controller, keyboard)
|
||||
}
|
||||
}
|
||||
|
||||
@ -107,15 +108,15 @@ impl Host for MiniFrontendBuilder {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn register_joystick(&mut self, device: JoystickDevice, input: Box<dyn JoystickUpdater>) -> Result<(), Error> {
|
||||
if device != JoystickDevice::A {
|
||||
fn register_controller(&mut self, device: ControllerDevice, input: Box<dyn ControllerUpdater>) -> Result<(), Error> {
|
||||
if device != ControllerDevice::A {
|
||||
return Ok(())
|
||||
}
|
||||
|
||||
if self.joystick.is_some() {
|
||||
return Err(Error::new("A joystick updater has already been registered with the frontend"));
|
||||
if self.controller.is_some() {
|
||||
return Err(Error::new("A controller updater has already been registered with the frontend"));
|
||||
}
|
||||
self.joystick = Some(input);
|
||||
self.controller = Some(input);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@ -132,16 +133,16 @@ impl Host for MiniFrontendBuilder {
|
||||
pub struct MiniFrontend {
|
||||
pub buffer: Vec<u32>,
|
||||
pub window: Option<Box<dyn WindowUpdater>>,
|
||||
pub joystick: Option<Box<dyn JoystickUpdater>>,
|
||||
pub controller: Option<Box<dyn ControllerUpdater>>,
|
||||
pub keyboard: Option<Box<dyn KeyboardUpdater>>,
|
||||
}
|
||||
|
||||
impl MiniFrontend {
|
||||
pub fn new(window: Option<Box<dyn WindowUpdater>>, joystick: Option<Box<dyn JoystickUpdater>>, keyboard: Option<Box<dyn KeyboardUpdater>>) -> Self {
|
||||
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],
|
||||
window,
|
||||
joystick,
|
||||
controller,
|
||||
keyboard,
|
||||
}
|
||||
}
|
||||
@ -184,19 +185,22 @@ impl MiniFrontend {
|
||||
}
|
||||
|
||||
if let Some(keys) = window.get_keys_pressed(minifb::KeyRepeat::Yes) {
|
||||
let mut modifiers: u16 = 0;
|
||||
let mut modifiers: u16 = 0x0000;
|
||||
for key in keys {
|
||||
if let Some(updater) = self.keyboard.as_mut() {
|
||||
updater.update_keyboard(map_key(key), true);
|
||||
}
|
||||
match key {
|
||||
Key::Enter => { modifiers |= 0xffff; },
|
||||
Key::A => { modifiers |= 0x0040; },
|
||||
Key::B => { modifiers |= 0x0010; },
|
||||
Key::Enter => { modifiers |= 0x0080; },
|
||||
Key::D => { system.as_ref().map(|s| s.enable_debugging()); },
|
||||
_ => { },
|
||||
}
|
||||
}
|
||||
if let Some(updater) = self.joystick.as_mut() {
|
||||
updater.update_joystick(modifiers);
|
||||
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() {
|
||||
|
19
src/host/controller.rs
Normal file
19
src/host/controller.rs
Normal file
@ -0,0 +1,19 @@
|
||||
|
||||
#[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,
|
||||
}
|
||||
|
@ -6,4 +6,5 @@ pub mod tty;
|
||||
|
||||
pub mod gfx;
|
||||
pub mod keys;
|
||||
pub mod controller;
|
||||
|
||||
|
@ -3,19 +3,12 @@ use std::sync::{Arc, Mutex, MutexGuard};
|
||||
|
||||
use crate::error::Error;
|
||||
use crate::host::keys::Key;
|
||||
|
||||
#[derive(Copy, Clone, Debug, PartialEq)]
|
||||
pub enum JoystickDevice {
|
||||
A,
|
||||
B,
|
||||
C,
|
||||
D,
|
||||
}
|
||||
use crate::host::controller::{ControllerDevice, Controller};
|
||||
|
||||
pub trait Host {
|
||||
//fn create_pty(&self) -> Result<Box<dyn Tty>, Error>;
|
||||
fn add_window(&mut self, updater: Box<dyn WindowUpdater>) -> Result<(), Error>;
|
||||
fn register_joystick(&mut self, _device: JoystickDevice, _input: Box<dyn JoystickUpdater>) -> Result<(), Error> { Err(Error::new("Not supported")) }
|
||||
fn register_controller(&mut self, _device: ControllerDevice, _input: Box<dyn ControllerUpdater>) -> Result<(), Error> { Err(Error::new("Not supported")) }
|
||||
fn register_keyboard(&mut self, _input: Box<dyn KeyboardUpdater>) -> Result<(), Error> { Err(Error::new("Not supported")) }
|
||||
}
|
||||
|
||||
@ -30,8 +23,8 @@ pub trait WindowUpdater: Send {
|
||||
fn update_frame(&mut self, width: u32, height: u32, bitmap: &mut [u32]);
|
||||
}
|
||||
|
||||
pub trait JoystickUpdater: Send {
|
||||
fn update_joystick(&mut self, modifiers: u16);
|
||||
pub trait ControllerUpdater: Send {
|
||||
fn update_controller(&mut self, data: Controller);
|
||||
}
|
||||
|
||||
pub trait KeyboardUpdater: Send {
|
||||
|
@ -17,8 +17,9 @@ use crate::host::traits::{Host};
|
||||
pub fn build_genesis<H: Host>(host: &mut H) -> Result<System, Error> {
|
||||
let mut system = System::new();
|
||||
|
||||
//let mut rom = MemoryBlock::load("binaries/genesis/GenTestV3.0.bin").unwrap();
|
||||
let mut rom = MemoryBlock::load("binaries/genesis/ComradeOj's tiny demo.bin").unwrap();
|
||||
let mut rom = MemoryBlock::load("binaries/genesis/GenTestV3.0.bin").unwrap();
|
||||
//let mut rom = MemoryBlock::load("binaries/genesis/HDRV_Genesis_Test_v1_4.bin").unwrap();
|
||||
//let mut rom = MemoryBlock::load("binaries/genesis/ComradeOj's tiny demo.bin").unwrap();
|
||||
//let mut rom = MemoryBlock::load("binaries/genesis/Sonic The Hedgehog (W) (REV 00) [!].bin").unwrap();
|
||||
//let mut rom = MemoryBlock::load("binaries/genesis/Sonic The Hedgehog (W) (REV 01) [!].bin").unwrap();
|
||||
//let mut rom = MemoryBlock::load("binaries/genesis/Sonic the Hedgehog 2 (JUE) [!].bin").unwrap();
|
||||
|
@ -75,12 +75,12 @@ impl Transmutable for MemoryBlock {
|
||||
}
|
||||
|
||||
|
||||
pub struct MemoryAdapter {
|
||||
pub struct AddressAdapter {
|
||||
pub subdevice: TransmutableBox,
|
||||
pub shift: u8,
|
||||
}
|
||||
|
||||
impl MemoryAdapter {
|
||||
impl AddressAdapter {
|
||||
pub fn new(subdevice: TransmutableBox, shift: u8) -> Self {
|
||||
Self {
|
||||
subdevice,
|
||||
@ -89,7 +89,7 @@ impl MemoryAdapter {
|
||||
}
|
||||
}
|
||||
|
||||
impl Addressable for MemoryAdapter {
|
||||
impl Addressable for AddressAdapter {
|
||||
fn len(&self) -> usize {
|
||||
let len = self.subdevice.borrow_mut().as_addressable().unwrap().len();
|
||||
len << self.shift
|
||||
@ -104,7 +104,7 @@ impl Addressable for MemoryAdapter {
|
||||
}
|
||||
}
|
||||
|
||||
impl Transmutable for MemoryAdapter {
|
||||
impl Transmutable for AddressAdapter {
|
||||
fn as_addressable(&mut self) -> Option<&mut dyn Addressable> {
|
||||
Some(self)
|
||||
}
|
||||
|
@ -1,7 +1,8 @@
|
||||
|
||||
use crate::error::Error;
|
||||
use crate::devices::{Address, Addressable, Transmutable};
|
||||
use crate::host::traits::{Host, JoystickDevice, JoystickUpdater, SharedData};
|
||||
use crate::host::controller::{ControllerDevice, Controller};
|
||||
use crate::host::traits::{Host, ControllerUpdater, SharedData};
|
||||
|
||||
|
||||
const REG_VERSION: Address = 0x01;
|
||||
@ -21,7 +22,7 @@ const DEV_NAME: &'static str = "genesis_controller";
|
||||
pub struct GenesisControllerPort {
|
||||
/// Data contains bits:
|
||||
/// 11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0
|
||||
/// X | Y | Z | MODE | START | A | B | C | RIGHT | LEFT | DOWN | UP
|
||||
/// X | Y | Z | MODE | START | A | C | B | RIGHT | LEFT | DOWN | UP
|
||||
pub data: SharedData<u16>,
|
||||
|
||||
pub ctrl: u8,
|
||||
@ -34,7 +35,7 @@ pub struct GenesisControllerPort {
|
||||
impl GenesisControllerPort {
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
data: SharedData::new(0),
|
||||
data: SharedData::new(0xffff),
|
||||
ctrl: 0,
|
||||
th_count: 0,
|
||||
next_read: 0,
|
||||
@ -73,10 +74,12 @@ impl GenesisControllerPort {
|
||||
|
||||
pub struct GenesisControllerUpdater(SharedData<u16>, SharedData<bool>);
|
||||
|
||||
impl JoystickUpdater for GenesisControllerUpdater {
|
||||
fn update_joystick(&mut self, modifiers: u16) {
|
||||
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 modifiers != 0 {
|
||||
if data.bits != 0 {
|
||||
self.1.set(true);
|
||||
}
|
||||
}
|
||||
@ -104,10 +107,10 @@ impl GenesisController {
|
||||
pub fn create<H: Host>(host: &mut H) -> Result<Self, Error> {
|
||||
let controller = GenesisController::new();
|
||||
|
||||
let joystick1 = Box::new(GenesisControllerUpdater(controller.port_1.data.clone(), controller.interrupt.clone()));
|
||||
host.register_joystick(JoystickDevice::A, joystick1)?;
|
||||
let joystick2 = Box::new(GenesisControllerUpdater(controller.port_2.data.clone(), controller.interrupt.clone()));
|
||||
host.register_joystick(JoystickDevice::B, joystick2)?;
|
||||
let controller1 = Box::new(GenesisControllerUpdater(controller.port_1.data.clone(), controller.interrupt.clone()));
|
||||
host.register_controller(ControllerDevice::A, controller1)?;
|
||||
let controller2 = Box::new(GenesisControllerUpdater(controller.port_2.data.clone(), controller.interrupt.clone()));
|
||||
host.register_controller(ControllerDevice::B, controller2)?;
|
||||
|
||||
Ok(controller)
|
||||
}
|
||||
|
@ -702,6 +702,9 @@ impl Inspectable for Ym7101 {
|
||||
"vram" => {
|
||||
self.state.dump_vram();
|
||||
},
|
||||
"vsram" => {
|
||||
self.state.dump_vsram();
|
||||
},
|
||||
_ => { },
|
||||
}
|
||||
Ok(())
|
||||
@ -740,5 +743,22 @@ impl Ym7101State {
|
||||
println!("{}", line);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn dump_vsram(&self) {
|
||||
let mut count = 80;
|
||||
let mut addr = 0;
|
||||
while count > 0 {
|
||||
let mut line = format!("{:#010x}: ", addr);
|
||||
|
||||
let to = if count < 16 { count / 2 } else { 8 };
|
||||
for _ in 0..to {
|
||||
let word = ((self.vsram[addr] as u16) << 8) | self.vsram[addr + 1] as u16;
|
||||
line += &format!("{:#06x} ", word);
|
||||
addr += 2;
|
||||
count -= 2;
|
||||
}
|
||||
println!("{}", line);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
4
todo.txt
4
todo.txt
@ -1,4 +1,8 @@
|
||||
|
||||
* should SharedData be HostData, or something else? I don't think the name is very informative
|
||||
* can you make the connections between things (like memory adapters), be expressed in a way that's more similar to the electrical design?
|
||||
like specifying that address pins 10-7 should be ignored/unconnected, pin 11 will connect to "chip select", etc
|
||||
|
||||
* movem still isn't working (for genesis)
|
||||
* fix movem tests
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user