Skip to content

Commit

Permalink
add some command line switches for the gpu window
Browse files Browse the repository at this point in the history
  • Loading branch information
exoticorn committed Jul 23, 2022
1 parent 465e66f commit 760664e
Show file tree
Hide file tree
Showing 12 changed files with 195 additions and 62 deletions.
3 changes: 3 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ browser = ["warp", "tokio", "tokio-stream", "webbrowser"]
[dependencies]
wasmtime = { version = "0.37.0", optional = true }
anyhow = "1"
env_logger = "0.9"
log = "0.4"
uw8-window = { path = "uw8-window", optional = true }
notify = "4"
pico-args = "0.4"
Expand Down
21 changes: 21 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,27 @@ Options:
-l LEVEL, --level LEVEL : Compression level (0-9). Higher compression levels are really slow.
-o FILE, --output FILE : Write the loaded and optionally packed cart back to disk.
when using the native runtime:
-m, --no-audio : Disable audio, also reduces cpu load a bit
--no-gpu : Force old cpu-only window code
--filter FILTER : Select an upscale filter at startup
--fullscreen : Start in fullscreen mode
Note that the cpu-only window does not support fullscreen nor upscale filters.
Unless --no-gpu is given, uw8 will first try to open a gpu accelerated window, falling back to the old cpu-only window if that fails.
Therefore you should rarely need to manually pass --no-gpu. If you prefer the old pixel doubling look to the now default crt filter,
you can just pass "--filter nearest" or "--filter 1".
The upscale filter options are:
1, nearest : Anti-aliased nearest filter
2, fast_crt : Very simple, cheap crt filter, not very good below a window size of 960x720
3, ss_crt : Super sampled crt filter, a little more demanding on the GPU but scales well to smaller window sizes
4, chromatic_crt : Variant of fast_crt with a slight offset of the three color dots of a pixel, still pretty cheap
5, auto_crt (default) : ss_crt below 960x720, chromatic_crt otherwise
You can switch the upscale filter at any time using the keys 1-5. You can toggle fullscreen with F.
uw8 pack [<options>] <infile> <outfile>
Expand Down
24 changes: 24 additions & 0 deletions site/content/docs.md
Original file line number Diff line number Diff line change
Expand Up @@ -436,6 +436,30 @@ and execution of the cart is stopped. Defaults to 30 (0.5s)
* `-l LEVEL`, `--level LEVEL`: Compression level (0-9). Higher compression levels are really slow.
* `-o FILE`, `--output FILE`: Write the loaded and optionally packed cart back to disk.

when using the native runtime:

* `-m`, `--no-audio`: Disable audio, also reduces cpu load a bit
* `--no-gpu`: Force old cpu-only window code
* `--filter FILTER`: Select an upscale filter at startup
* `--fullscreen`: Start in fullscreen mode

Note that the cpu-only window does not support fullscreen nor upscale filters.

Unless --no-gpu is given, uw8 will first try to open a gpu accelerated window, falling back to the old cpu-only window if that fails.
Therefore you should rarely need to manually pass --no-gpu. If you prefer the old pixel doubling look to the now default crt filter,
you can just pass `--filter nearest` or `--filter 1`.

The upscale filter options are:
```
1, nearest : Anti-aliased nearest filter
2, fast_crt : Very simple, cheap crt filter, not very good below a window size of 960x720
3, ss_crt : Super sampled crt filter, a little more demanding on the GPU but scales well to smaller window sizes
4, chromatic_crt : Variant of fast_crt with a slight offset of the three color dots of a pixel, still pretty cheap
5, auto_crt (default) : ss_crt below 960x720, chromatic_crt otherwise
```

You can switch the upscale filter at any time using the keys 1-5. You can toggle fullscreen with F.

## `uw8 pack`

Usage:
Expand Down
20 changes: 15 additions & 5 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ use uw8::RunWebServer;
use uw8::Runtime;

fn main() -> Result<()> {
env_logger::Builder::from_env(env_logger::Env::default()).init();
let mut args = Arguments::from_env();

// try to enable ansi support in win10 cmd shell
Expand All @@ -35,7 +36,7 @@ fn main() -> Result<()> {
println!();
println!("Usage:");
#[cfg(any(feature = "native", feature = "browser"))]
println!(" uw8 run [-t/--timeout <frames>] [--no-gpu] [--b/--browser] [-w/--watch] [-p/--pack] [-u/--uncompressed] [-l/--level] [-o/--output <out-file>] <file>");
println!(" uw8 run [-t/--timeout <frames>] [--b/--browser] [-w/--watch] [-p/--pack] [-u/--uncompressed] [-l/--level] [-o/--output <out-file>] <file>");
println!(" uw8 pack [-u/--uncompressed] [-l/--level] <in-file> <out-file>");
println!(" uw8 unpack <in-file> <out-file>");
println!(" uw8 compile [-d/--debug] <in-file> <out-file>");
Expand All @@ -54,8 +55,6 @@ fn run(mut args: Arguments) -> Result<()> {
let watch_mode = args.contains(["-w", "--watch"]);
#[allow(unused)]
let timeout: Option<u32> = args.opt_value_from_str(["-t", "--timeout"])?;
#[allow(unused)]
let gpu = !args.contains("--no-gpu");

let mut config = Config::default();
if args.contains(["-p", "--pack"]) {
Expand All @@ -82,20 +81,31 @@ fn run(mut args: Arguments) -> Result<()> {
#[cfg(not(feature = "native"))]
let run_browser = args.contains(["-b", "--browser"]) || true;

let disable_audio = args.contains(["-m", "--disable-audio"]);
let disable_audio = args.contains(["-m", "--no-audio"]);

#[cfg(feature = "native")]
let window_config = {
let mut config = WindowConfig::default();
if !run_browser {
config.parse_arguments(&mut args);
}
config
};

let filename = args.free_from_os_str::<PathBuf, bool>(|s| Ok(s.into()))?;

let mut watcher = uw8::FileWatcher::new()?;

use std::process::exit;

use uw8_window::WindowConfig;

let mut runtime: Box<dyn Runtime> = if !run_browser {
#[cfg(not(feature = "native"))]
unimplemented!();
#[cfg(feature = "native")]
{
let mut microw8 = MicroW8::new(timeout, gpu)?;
let mut microw8 = MicroW8::new(timeout, window_config)?;
if disable_audio {
microw8.disable_audio();
}
Expand Down
6 changes: 3 additions & 3 deletions src/run_native.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use std::{thread, time::Instant};
use anyhow::{anyhow, Result};
use cpal::traits::*;
use rubato::Resampler;
use uw8_window::Window;
use uw8_window::{Window, WindowConfig};
use wasmtime::{
Engine, GlobalType, Memory, MemoryType, Module, Mutability, Store, TypedFunc, ValType,
};
Expand Down Expand Up @@ -45,7 +45,7 @@ struct UW8WatchDog {
}

impl MicroW8 {
pub fn new(timeout: Option<u32>, gpu: bool) -> Result<MicroW8> {
pub fn new(timeout: Option<u32>, window_config: WindowConfig) -> Result<MicroW8> {
let mut config = wasmtime::Config::new();
config.cranelift_opt_level(wasmtime::OptLevel::Speed);
if timeout.is_some() {
Expand All @@ -56,7 +56,7 @@ impl MicroW8 {
let loader_module =
wasmtime::Module::new(&engine, include_bytes!("../platform/bin/loader.wasm"))?;

let window = Window::new(gpu)?;
let window = Window::new(window_config)?;

Ok(MicroW8 {
window,
Expand Down
7 changes: 7 additions & 0 deletions uw8-window/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions uw8-window/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ edition = "2021"
winit = "0.26.1"
env_logger = "0.9"
log = "0.4"
pico-args = "0.4"
wgpu = "0.13.1"
pollster = "0.2"
bytemuck = { version = "1.4", features = [ "derive" ] }
Expand Down
2 changes: 1 addition & 1 deletion uw8-window/src/cpu.rs
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,6 @@ impl WindowImpl for Window {
}

fn is_open(&self) -> bool {
self.window.is_open()
self.window.is_open() && !self.window.is_key_down(Key::Escape)
}
}
120 changes: 71 additions & 49 deletions uw8-window/src/gpu/mod.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use crate::{Input, WindowImpl};
use crate::{Input, WindowConfig, WindowImpl};
use anyhow::{anyhow, Result};
use std::{num::NonZeroU32, time::Instant};

Expand Down Expand Up @@ -37,13 +37,18 @@ pub struct Window {
}

impl Window {
pub fn new() -> Result<Window> {
async fn create() -> Result<Window> {
pub fn new(window_config: WindowConfig) -> Result<Window> {
async fn create(window_config: WindowConfig) -> Result<Window> {
let event_loop = EventLoop::new();
let window = WindowBuilder::new()
.with_inner_size(PhysicalSize::new(640u32, 480))
.with_min_inner_size(PhysicalSize::new(320u32, 240))
.with_title("MicroW8")
.with_fullscreen(if window_config.fullscreen {
Some(Fullscreen::Borderless(None))
} else {
None
})
.build(&event_loop)?;

window.set_cursor_visible(false);
Expand Down Expand Up @@ -73,12 +78,13 @@ impl Window {
present_mode: wgpu::PresentMode::AutoNoVsync,
};

let filter: Box<dyn Filter> = Box::new(AutoCrtFilter::new(
let filter: Box<dyn Filter> = create_filter(
&device,
&palette_screen_mode.screen_view,
window.inner_size(),
surface_config.format,
));
window_config.filter,
);

surface.configure(&device, &surface_config);

Expand All @@ -95,12 +101,12 @@ impl Window {
filter,
gamepads: [0; 4],
next_frame: Instant::now(),
is_fullscreen: false,
is_fullscreen: window_config.fullscreen,
is_open: true,
})
}

pollster::block_on(create())
pollster::block_on(create(window_config))
}
}

Expand All @@ -109,6 +115,7 @@ impl WindowImpl for Window {
let mut reset = false;
self.event_loop.run_return(|event, _, control_flow| {
*control_flow = ControlFlow::WaitUntil(self.next_frame);
let mut new_filter = None;
match event {
Event::WindowEvent { event, .. } => match event {
WindowEvent::Resized(new_size) => {
Expand Down Expand Up @@ -153,48 +160,11 @@ impl WindowImpl for Window {
self.window.set_fullscreen(fullscreen);
}
Some(VirtualKeyCode::R) => reset = true,
Some(VirtualKeyCode::Key1) => {
self.filter = Box::new(SquareFilter::new(
&self.device,
&self.palette_screen_mode.screen_view,
self.window.inner_size(),
self.surface_config.format,
))
}
Some(VirtualKeyCode::Key2) => {
self.filter = Box::new(FastCrtFilter::new(
&self.device,
&self.palette_screen_mode.screen_view,
self.window.inner_size(),
self.surface_config.format,
false,
))
}
Some(VirtualKeyCode::Key3) => {
self.filter = Box::new(CrtFilter::new(
&self.device,
&self.palette_screen_mode.screen_view,
self.window.inner_size(),
self.surface_config.format,
))
}
Some(VirtualKeyCode::Key4) => {
self.filter = Box::new(FastCrtFilter::new(
&self.device,
&self.palette_screen_mode.screen_view,
self.window.inner_size(),
self.surface_config.format,
true,
))
}
Some(VirtualKeyCode::Key5) => {
self.filter = Box::new(AutoCrtFilter::new(
&self.device,
&self.palette_screen_mode.screen_view,
self.window.inner_size(),
self.surface_config.format,
))
}
Some(VirtualKeyCode::Key1) => new_filter = Some(1),
Some(VirtualKeyCode::Key2) => new_filter = Some(2),
Some(VirtualKeyCode::Key3) => new_filter = Some(3),
Some(VirtualKeyCode::Key4) => new_filter = Some(4),
Some(VirtualKeyCode::Key5) => new_filter = Some(5),
_ => (),
}

Expand All @@ -215,6 +185,15 @@ impl WindowImpl for Window {
}
_ => (),
}
if let Some(new_filter) = new_filter {
self.filter = create_filter(
&self.device,
&self.palette_screen_mode.screen_view,
self.window.inner_size(),
self.surface_config.format,
new_filter,
);
}
});
Input {
gamepads: self.gamepads,
Expand Down Expand Up @@ -269,6 +248,49 @@ impl WindowImpl for Window {
}
}

fn create_filter(
device: &wgpu::Device,
screen_texture: &wgpu::TextureView,
window_size: PhysicalSize<u32>,
surface_format: wgpu::TextureFormat,
filter: u32,
) -> Box<dyn Filter> {
match filter {
1 => Box::new(SquareFilter::new(
device,
screen_texture,
window_size,
surface_format,
)),
2 => Box::new(FastCrtFilter::new(
device,
screen_texture,
window_size,
surface_format,
false,
)),
3 => Box::new(CrtFilter::new(
device,
screen_texture,
window_size,
surface_format,
)),
4 => Box::new(FastCrtFilter::new(
device,
screen_texture,
window_size,
surface_format,
true,
)),
_ => Box::new(AutoCrtFilter::new(
device,
screen_texture,
window_size,
surface_format,
)),
}
}

trait Filter {
fn resize(&mut self, queue: &wgpu::Queue, new_size: PhysicalSize<u32>);
fn render<'a>(&'a self, render_pass: &mut wgpu::RenderPass<'a>);
Expand Down
Loading

0 comments on commit 760664e

Please sign in to comment.