Skip to content

Commit

Permalink
Clipboard web (#280)
Browse files Browse the repository at this point in the history
  • Loading branch information
lukexor authored Jun 7, 2024
1 parent e6941d8 commit 9e21835
Show file tree
Hide file tree
Showing 11 changed files with 669 additions and 346 deletions.
3 changes: 3 additions & 0 deletions .cargo/config.toml
Original file line number Diff line number Diff line change
@@ -1,2 +1,5 @@
[build]
rustflags = ["-Z", "threads=8"]

[target.'cfg(target_arch = "wasm32")']
rustflags = ["-Z", "threads=8", "--cfg=web_sys_unstable_apis"]
3 changes: 3 additions & 0 deletions tetanes/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,9 @@ puffin = { workspace = true, features = ["web"], optional = true }
tracing-web = "0.1"
wgpu = { version = "0.19", features = ["webgl"] }
web-sys = { workspace = true, features = [
"Clipboard",
"ClipboardEvent",
"DataTransfer",
"Document",
"DomTokenList",
"Element",
Expand Down
7 changes: 4 additions & 3 deletions tetanes/src/nes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -182,13 +182,14 @@ impl Nes {
.init_state
.take()
.context("config unexpectedly already taken")?;
let emulation = Emulation::new(tx.clone(), frame_tx.clone(), cfg.clone())?;
let renderer =
Renderer::new(tx.clone(), event_loop, resources, frame_rx, cfg.clone())?;

let input_bindings = InputBindings::from_input_config(&cfg.input);
let gamepads = Gamepads::new();
cfg.input.update_gamepad_assignments(&gamepads);

let emulation = Emulation::new(tx.clone(), frame_tx.clone(), &cfg)?;
let renderer = Renderer::new(tx.clone(), event_loop, resources, frame_rx, &cfg)?;

let mut running = Running {
cfg,
tx,
Expand Down
13 changes: 5 additions & 8 deletions tetanes/src/nes/audio.rs
Original file line number Diff line number Diff line change
Expand Up @@ -347,14 +347,11 @@ impl Output {
};
let supported =
supports_sample_rate && supports_sample_format && supports_buffer_size;
debug!(
"{} config: {config:?}",
if supported {
"supported"
} else {
"unsupported"
}
);
if supported {
debug!("supported config: {config:?}",);
} else {
trace!("unsupported config: {config:?}",);
}
supported
})
.or_else(|| {
Expand Down
15 changes: 9 additions & 6 deletions tetanes/src/nes/emulation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -162,25 +162,28 @@ impl Multi {
fn spawn(
proxy_tx: EventLoopProxy<NesEvent>,
frame_tx: BufSender<Frame, FrameRecycle>,
config: Config,
cfg: &Config,
) -> anyhow::Result<Self> {
let (tx, rx) = channel::bounded(1024);
Ok(Self {
tx,
handle: std::thread::Builder::new()
.name("emulation".into())
.spawn(move || Self::main(proxy_tx, rx, frame_tx, config))?,
.spawn({
let cfg = cfg.clone();
move || Self::main(proxy_tx, rx, frame_tx, &cfg)
})?,
})
}

fn main(
tx: EventLoopProxy<NesEvent>,
rx: channel::Receiver<NesEvent>,
frame_tx: BufSender<Frame, FrameRecycle>,
config: Config,
cfg: &Config,
) {
debug!("emulation thread started");
let mut state = State::new(tx, frame_tx, config); // Has to be created on the thread, since
let mut state = State::new(tx, frame_tx, cfg); // Has to be created on the thread, since
loop {
#[cfg(feature = "profiling")]
puffin::profile_scope!("emulation loop");
Expand All @@ -205,7 +208,7 @@ impl Emulation {
pub fn new(
tx: EventLoopProxy<NesEvent>,
frame_tx: BufSender<Frame, FrameRecycle>,
cfg: Config,
cfg: &Config,
) -> anyhow::Result<Self> {
let threaded = cfg.emulation.threaded
&& std::thread::available_parallelism().map_or(false, |count| count.get() > 1);
Expand Down Expand Up @@ -281,7 +284,7 @@ impl State {
fn new(
tx: EventLoopProxy<NesEvent>,
frame_tx: BufSender<Frame, FrameRecycle>,
cfg: Config,
cfg: &Config,
) -> Self {
let mut control_deck = ControlDeck::with_config(cfg.deck.clone());
let audio = Audio::new(
Expand Down
19 changes: 8 additions & 11 deletions tetanes/src/nes/event.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ use crate::{
use anyhow::anyhow;
use egui::ViewportId;
use serde::{Deserialize, Serialize};
use std::path::PathBuf;
use std::path::{Path, PathBuf};
use tetanes_core::{
action::Action as DeckAction,
apu::Channel,
Expand Down Expand Up @@ -482,16 +482,13 @@ impl Running {
UiEvent::Message((ty, msg)) => self.renderer.add_message(ty, msg),
UiEvent::Error(err) => self.renderer.on_error(anyhow!(err)),
UiEvent::LoadRomDialog => {
match open_file_dialog(
"Load ROM",
"NES ROMs",
&["nes"],
self.cfg
.renderer
.roms_path
.as_ref()
.map_or_else(|| PathBuf::from("."), |p| p.to_path_buf()),
) {
let dir = self
.cfg
.renderer
.roms_path
.as_deref()
.unwrap_or_else(|| Path::new("."));
match open_file_dialog("Load ROM", "NES ROMs", &["nes"], dir) {
Ok(maybe_path) => {
if let Some(path) = maybe_path {
self.nes_event(EmulationEvent::LoadRomPath(path));
Expand Down
27 changes: 3 additions & 24 deletions tetanes/src/nes/input.rs
Original file line number Diff line number Diff line change
Expand Up @@ -212,27 +212,6 @@ impl ActionBindings {
{ (Player::One, JoypadBtn::Select) => KeyW },
{ (Player::One, JoypadBtn::Start) => KeyQ },
),
Player::Two => shortcut_map!(
{ (Player::Two, JoypadBtn::A) => KeyN },
{ (Player::Two, JoypadBtn::B) => KeyM },
{ (Player::Two, JoypadBtn::Up) => KeyI },
{ (Player::Two, JoypadBtn::Down) => KeyK },
{ (Player::Two, JoypadBtn::Left) => KeyJ },
{ (Player::Two, JoypadBtn::Right) => KeyL },
{ (Player::Two, JoypadBtn::Select) => Digit9 },
{ (Player::Two, JoypadBtn::Start) => Digit8 },
),
#[cfg(debug_assertions)]
Player::Three => shortcut_map!(
{ (Player::Three, JoypadBtn::A) => KeyV },
{ (Player::Three, JoypadBtn::B) => KeyB },
{ (Player::Three, JoypadBtn::Up) => KeyT },
{ (Player::Three, JoypadBtn::Down) => KeyG },
{ (Player::Three, JoypadBtn::Left) => KeyF },
{ (Player::Three, JoypadBtn::Right) => KeyH },
{ (Player::Three, JoypadBtn::Select) => Digit6 },
{ (Player::Three, JoypadBtn::Start) => Digit5 },
),
_ => Vec::new(),
};

Expand All @@ -254,12 +233,12 @@ impl ActionBindings {
pub struct InputBindings(HashMap<Input, Action>);

impl InputBindings {
pub fn from_input_config(config: &InputConfig) -> Self {
pub fn from_input_config(cfg: &InputConfig) -> Self {
let mut map = HashMap::with_capacity(256);
for bind in config
for bind in cfg
.shortcuts
.iter()
.chain(config.joypad_bindings.iter().flatten())
.chain(cfg.joypad_bindings.iter().flatten())
{
for input in bind.bindings.into_iter().flatten() {
map.insert(input, bind.action);
Expand Down
Loading

0 comments on commit 9e21835

Please sign in to comment.