Renamed joystick to controller in host traits

This commit is contained in:
transistor 2021-12-02 15:04:41 -08:00
parent b165e18fac
commit 9464e4c75a
9 changed files with 89 additions and 44 deletions

View File

@ -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
View 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,
}

View File

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

View File

@ -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 {

View File

@ -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();

View File

@ -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)
}

View File

@ -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)
}

View File

@ -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);
}
}
}

View File

@ -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