aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Cargo.lock89
-rw-r--r--Cargo.toml2
-rw-r--r--src/bin.rs149
3 files changed, 145 insertions, 95 deletions
diff --git a/Cargo.lock b/Cargo.lock
index e2ef605..7098de0 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -5,13 +5,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "atty"
-version = "0.2.3"
+version = "0.2.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
- "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
- "libc 0.2.34 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)",
"termion 1.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
+ "winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@@ -31,11 +30,11 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "clap"
-version = "2.29.0"
+version = "2.29.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"ansi_term 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)",
- "atty 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
+ "atty 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
"bitflags 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
"strsim 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
"textwrap 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -45,28 +44,17 @@ dependencies = [
[[package]]
name = "fuchsia-zircon"
-version = "0.2.1"
+version = "0.3.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
- "fuchsia-zircon-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "bitflags 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "fuchsia-zircon-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "fuchsia-zircon-sys"
-version = "0.2.0"
+version = "0.3.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
-dependencies = [
- "bitflags 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
-]
-
-[[package]]
-name = "kernel32-sys"
-version = "0.2.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-dependencies = [
- "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
- "winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
-]
[[package]]
name = "lazy_static"
@@ -75,7 +63,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "libc"
-version = "0.2.34"
+version = "0.2.36"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
@@ -112,16 +100,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "rand"
-version = "0.3.18"
+version = "0.3.20"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
- "fuchsia-zircon 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "libc 0.2.34 (registry+https://github.com/rust-lang/crates.io-index)",
+ "fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "redox_syscall"
-version = "0.1.32"
+version = "0.1.37"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
@@ -129,14 +117,14 @@ name = "redox_termios"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
- "redox_syscall 0.1.32 (registry+https://github.com/rust-lang/crates.io-index)",
+ "redox_syscall 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "runes"
-version = "0.1.7"
+version = "0.1.8"
dependencies = [
- "clap 2.29.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "clap 2.29.2 (registry+https://github.com/rust-lang/crates.io-index)",
"sdl2 0.31.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
@@ -147,9 +135,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"bitflags 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
"lazy_static 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
- "libc 0.2.34 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)",
"num 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)",
- "rand 0.3.18 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rand 0.3.20 (registry+https://github.com/rust-lang/crates.io-index)",
"sdl2-sys 0.31.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
@@ -171,8 +159,8 @@ name = "termion"
version = "1.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
- "libc 0.2.34 (registry+https://github.com/rust-lang/crates.io-index)",
- "redox_syscall 0.1.32 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)",
+ "redox_syscall 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)",
"redox_termios 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
@@ -196,32 +184,40 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "winapi"
-version = "0.2.8"
+version = "0.3.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
+]
[[package]]
-name = "winapi-build"
-version = "0.1.1"
+name = "winapi-i686-pc-windows-gnu"
+version = "0.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
+[[package]]
+name = "winapi-x86_64-pc-windows-gnu"
+version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[metadata]
"checksum ansi_term 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6b3568b48b7cefa6b8ce125f9bb4989e52fbcc29ebea88df04cc7c5f12f70455"
-"checksum atty 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "21e50800ec991574876040fff8ee46b136a53e985286fbe6a3bdfe6421b78860"
+"checksum atty 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "8352656fd42c30a0c3c89d26dea01e3b77c0ab2af18230835c15e2e13cd51859"
"checksum bitflags 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "aad18937a628ec6abcd26d1489012cc0e18c21798210f491af69ded9b881106d"
"checksum bitflags 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b3c30d3802dfb7281680d6285f2ccdaa8c2d8fee41f93805dba5c4cf50dc23cf"
"checksum cfg-if 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "d4c819a1287eb618df47cc647173c5c4c66ba19d888a6e50d605672aed3140de"
-"checksum clap 2.29.0 (registry+https://github.com/rust-lang/crates.io-index)" = "110d43e343eb29f4f51c1db31beb879d546db27998577e5715270a54bcf41d3f"
-"checksum fuchsia-zircon 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "f6c0581a4e363262e52b87f59ee2afe3415361c6ec35e665924eb08afe8ff159"
-"checksum fuchsia-zircon-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "43f3795b4bae048dc6123a6b972cadde2e676f9ded08aef6bb77f5f157684a82"
-"checksum kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d"
+"checksum clap 2.29.2 (registry+https://github.com/rust-lang/crates.io-index)" = "4151c5790817c7d21bbdc6c3530811f798172915f93258244948b93ba19604a6"
+"checksum fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2e9763c69ebaae630ba35f74888db465e49e259ba1bc0eda7d06f4a067615d82"
+"checksum fuchsia-zircon-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "3dcaa9ae7725d12cdb85b3ad99a434db70b468c09ded17e012d86b5c1010f7a7"
"checksum lazy_static 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "76f033c7ad61445c5b347c7382dd1237847eb1bce590fe50365dcb33d546be73"
-"checksum libc 0.2.34 (registry+https://github.com/rust-lang/crates.io-index)" = "36fbc8a8929c632868295d0178dd8f63fc423fd7537ad0738372bd010b3ac9b0"
+"checksum libc 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)" = "1e5d97d6708edaa407429faa671b942dc0f2727222fb6b6539bf1db936e4b121"
"checksum num 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)" = "cc4083e14b542ea3eb9b5f33ff48bd373a92d78687e74f4cc0a30caeb754f0ca"
"checksum num-integer 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)" = "d1452e8b06e448a07f0e6ebb0bb1d92b8890eea63288c0b627331d53514d0fba"
"checksum num-iter 0.1.34 (registry+https://github.com/rust-lang/crates.io-index)" = "7485fcc84f85b4ecd0ea527b14189281cf27d60e583ae65ebc9c088b13dffe01"
"checksum num-traits 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)" = "cacfcab5eb48250ee7d0c7896b51a2c5eec99c1feea5f32025635f5ae4b00070"
-"checksum rand 0.3.18 (registry+https://github.com/rust-lang/crates.io-index)" = "6475140dfd8655aeb72e1fd4b7a1cc1c202be65d71669476e392fe62532b9edd"
-"checksum redox_syscall 0.1.32 (registry+https://github.com/rust-lang/crates.io-index)" = "ab105df655884ede59d45b7070c8a65002d921461ee813a024558ca16030eea0"
+"checksum rand 0.3.20 (registry+https://github.com/rust-lang/crates.io-index)" = "512870020642bb8c221bf68baa1b2573da814f6ccfe5c9699b1c303047abe9b1"
+"checksum redox_syscall 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)" = "0d92eecebad22b767915e4d529f89f28ee96dbbf5a4810d2b844373f136417fd"
"checksum redox_termios 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7e891cfe48e9100a70a3b6eb652fef28920c117d366339687bd5576160db0f76"
"checksum sdl2 0.31.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a74c2a98a354b20713b90cce70aef9e927e46110d1bc4ef728fd74e0d53eba60"
"checksum sdl2-sys 0.31.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5c543ce8a6e33a30cb909612eeeb22e693848211a84558d5a00bb11e791b7ab7"
@@ -230,5 +226,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
"checksum textwrap 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c0b59b6b4b44d867f1370ef1bd91bfb262bf07bf0ae65c202ea2fbc16153b693"
"checksum unicode-width 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "bf3a113775714a22dcb774d8ea3655c53a32debae63a063acc00a91cc586245f"
"checksum vec_map 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "887b5b631c2ad01628bbbaa7dd4c869f80d3186688f8d0b6f58774fbe324988c"
-"checksum winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "167dc9d6949a9b857f3451275e911c3f44255842c1f7a76f33c55103a909087a"
-"checksum winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2d315eee3b34aca4797b2da6b13ed88266e6d612562a0c46390af8299fc699bc"
+"checksum winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "04e3bd221fcbe8a271359c04f21a76db7d0c6028862d1bb5512d85e1e2eb5bb3"
+"checksum winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
+"checksum winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
diff --git a/Cargo.toml b/Cargo.toml
index 6b90d64..27a5d3f 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -1,6 +1,6 @@
[package]
name = "runes"
-version = "0.1.8"
+version = "0.1.9"
authors = ["Determinant <[email protected]>"]
description = "No-std NES emulator library and minimal emulator written purely in Rust."
repository = "https://github.com/Determinant/runes"
diff --git a/src/bin.rs b/src/bin.rs
index 08f2f59..4e0a550 100644
--- a/src/bin.rs
+++ b/src/bin.rs
@@ -10,12 +10,9 @@ use std::cell::{Cell, RefCell};
extern crate sdl2;
#[macro_use] extern crate clap;
-use sdl2::event::Event;
-use sdl2::keyboard::Keycode;
-use sdl2::rect::Rect;
use clap::{Arg, App};
- mod utils;
+mod utils;
mod memory;
#[macro_use] mod mos6502;
mod ppu;
@@ -48,7 +45,7 @@ const PIX_HEIGHT: u32 = 240;
const FB_PITCH: usize = PIX_WIDTH as usize * 3;
const FB_SIZE: usize = PIX_HEIGHT as usize * FB_PITCH;
const AUDIO_SAMPLES: u16 = 4410;
-const AUDIO_EXTRA_SAMPLES: u16 = 20;
+const AUDIO_EXTRA_SAMPLES: u16 = 1000;
const AUDIO_ALL_SAMPLES: u16 = AUDIO_SAMPLES + AUDIO_EXTRA_SAMPLES;
pub struct SimpleCart {
@@ -155,46 +152,54 @@ impl utils::Write for FileIO {
}
}
-
-macro_rules! gen_keymap {
- ($tab: ident, [$($x: expr, $y: expr), *]) => {
- {$($tab[($x as usize) & 0xff] = $y;)*}
- };
-}
-
struct SDLEventPoller {
events: RefCell<sdl2::EventPump>,
p1_button_state: Cell<u8>,
- keymap: [u8; 256],
- exit_flag: Cell<bool>
+ exit_flag: Cell<bool>,
+}
+
+fn keyboard_mapping(code: sdl2::keyboard::Keycode) -> u8 {
+ use sdl2::keyboard::Keycode::*;
+ match code {
+ I => stdctl::UP,
+ K => stdctl::DOWN,
+ J => stdctl::LEFT,
+ L => stdctl::RIGHT,
+ Z => stdctl::A,
+ X => stdctl::B,
+ Return => stdctl::START,
+ S => stdctl::SELECT,
+ Up => stdctl::UP,
+ Down => stdctl::DOWN,
+ Left => stdctl::LEFT,
+ Right => stdctl::RIGHT,
+ _ => 0,
+ }
+}
+
+fn joystick_mapping(button: sdl2::controller::Button) -> u8 {
+ use sdl2::controller::Button::*;
+ match button {
+ DPadUp => stdctl::UP,
+ DPadDown => stdctl::DOWN,
+ DPadLeft => stdctl::LEFT,
+ DPadRight => stdctl::RIGHT,
+ A => stdctl::A,
+ B => stdctl::B,
+ X => stdctl::A,
+ Y => stdctl::B,
+ Start => stdctl::START,
+ _ => stdctl::SELECT
+ }
}
impl SDLEventPoller {
fn new(_events: sdl2::EventPump) -> Self {
- let mut res = SDLEventPoller {
+ SDLEventPoller {
events: RefCell::new(_events),
p1_button_state: Cell::new(0),
- exit_flag: Cell::new(false),
- keymap: [stdctl::NULL; 256]
- };
- use Keycode::*;
- {
- let keymap = &mut res.keymap;
- gen_keymap!(keymap, [I, stdctl::UP,
- K, stdctl::DOWN,
- J, stdctl::LEFT,
- L, stdctl::RIGHT,
- Z, stdctl::A,
- X, stdctl::B,
- Return, stdctl::START,
- S, stdctl::SELECT,
- Up, stdctl::UP,
- Down, stdctl::DOWN,
- Left, stdctl::LEFT,
- Right, stdctl::RIGHT
- ]);
+ exit_flag: Cell::new(false)
}
- res
}
#[inline]
@@ -206,20 +211,38 @@ impl SDLEventPoller {
impl InputPoller for SDLEventPoller {
#[inline]
fn poll(&self) -> u8 {
- use Keycode::*;
- let keymap = &self.keymap;
+ use sdl2::keyboard::Keycode::Escape;
+ use sdl2::event::Event;
let mut ns = self.p1_button_state.get();
for event in self.events.borrow_mut().poll_iter() {
match event {
Event::Quit {..} | Event::KeyDown { keycode: Some(Escape), .. } => {
self.exit_flag.set(true)
},
- Event::KeyDown { keycode: Some(c), .. } => {
- ns |= keymap[(c as usize) & 0xff]
- },
- Event::KeyUp { keycode: Some(c), .. } => {
- ns &= !keymap[(c as usize) & 0xff]
+ Event::KeyDown { keycode: Some(c), .. } =>
+ ns |= keyboard_mapping(c),
+ Event::KeyUp { keycode: Some(c), .. } =>
+ ns &= !keyboard_mapping(c),
+ Event::ControllerButtonDown { button, .. } =>
+ ns |= joystick_mapping(button),
+ Event::ControllerButtonUp { button, .. } =>
+ ns &= !joystick_mapping(button),
+ /* TODO: support axis motion
+ Event::ControllerAxisMotion { axis: LeftX, value: val, .. } => {
+ let threshold = 10_000;
+ if val > threshold {
+ println!("{}", val);
+ ns |= stdctl::RIGHT;
+ ns &= !stdctl::LEFT;
+ } else if val < -threshold {
+ println!("{}", val);
+ ns |= stdctl::LEFT;
+ ns &= !stdctl::RIGHT;
+ } else {
+ ns &= !(stdctl::RIGHT | stdctl::LEFT);
+ }
},
+ */
_ => ()
}
}
@@ -232,7 +255,7 @@ struct SDLWindow<'a> {
canvas: sdl2::render::WindowCanvas,
frame_buffer: [u8; FB_SIZE],
texture: sdl2::render::Texture,
- copy_area: Option<Rect>,
+ copy_area: Option<sdl2::rect::Rect>,
event: &'a SDLEventPoller
}
@@ -246,7 +269,7 @@ impl<'a> SDLWindow<'a> {
let mut copy_area = None;
if !full_screen {
actual_height -= 16 * pixel_scale;
- copy_area = Some(Rect::new(0, 8, PIX_WIDTH, PIX_HEIGHT - 16));
+ copy_area = Some(sdl2::rect::Rect::new(0, 8, PIX_WIDTH, PIX_HEIGHT - 16));
}
let window = video_subsystem.window("RuNES", actual_width, actual_height)
.position_centered()
@@ -525,11 +548,13 @@ fn main() {
println!("read prg {}", file.read(&mut prg_rom[..]).unwrap());
println!("read chr {}", file.read(&mut chr_rom[..]).unwrap());
- /* SDL setup */
+ /* setup SDL */
let sdl_context = sdl2::init().unwrap();
- let event = SDLEventPoller::new(sdl_context.event_pump().unwrap());
+ let controller_subsystem = sdl_context.game_controller().unwrap();
let video_subsystem = sdl_context.video().unwrap();
let audio_subsystem = sdl_context.audio().unwrap();
+
+ /* audio */
let audio_sync = AudioSync { time_barrier: Condvar::new(),
buffer: Mutex::new((CircularBuffer::new(),
AUDIO_ALL_SAMPLES))};
@@ -542,7 +567,33 @@ fn main() {
let device = audio_subsystem.open_playback(None, &desired_spec, |_| {
SDLAudioPlayback(&audio_sync)
}).unwrap();
- let mut win = SDLWindow::new(&video_subsystem, &event, /*&p1ctl, */ scale, full);
+
+ /* joysticks */
+ let njoysticks = match controller_subsystem.num_joysticks() {
+ Ok(n) => n,
+ Err(e) => {
+ println!("can't enumerate joysticks: {}", e);
+ 0
+ },
+ };
+ println!("detected {} joysticks", njoysticks);
+ let mut _sdl_joystick = None;
+ for id in 0..njoysticks {
+ if controller_subsystem.is_game_controller(id) {
+ match controller_subsystem.open(id) {
+ Ok(ctl) => {
+ println!("opened controller {}", ctl.name());
+ println!("controller mapping: {}", ctl.mapping());
+ _sdl_joystick = Some(ctl);
+ break;
+ },
+ Err(e) => println!("failed to open {}: {}", id, e)
+ }
+ }
+ }
+
+ let event = SDLEventPoller::new(sdl_context.event_pump().unwrap());
+ let mut win = SDLWindow::new(&video_subsystem, &event, scale, full);
/* construct mapper from cartridge data */
let cart = SimpleCart::new(chr_rom, prg_rom, sram, mirror);
@@ -553,15 +604,17 @@ fn main() {
_ => panic!("unsupported mapper {}", mapper_id)
};
- /* P1 controller */
+ /* controller for player 1 */
let p1ctl = stdctl::Joystick::new(&event);
+ /* setup the emulated machine */
let mapper = mapper::RefMapper::new(&mut (*m) as &mut mapper::Mapper);
let mut cpu = CPU::new(CPUMemory::new(&mapper, Some(&p1ctl), None));
let mut ppu = PPU::new(PPUMemory::new(&mapper), &mut win);
let mut apu = APU::new(&mut spkr);
let cpu_ptr = &mut cpu as *mut CPU;
cpu.mem.bus.attach(cpu_ptr, &mut ppu, &mut apu);
+
let load_state = !no_state && match match load_state_name {
Some(s) => Some(File::open(s).unwrap()),
None => match File::open(&default_state_name) {