From 9e836927c407fde4e244522b10366be2d69bcec6 Mon Sep 17 00:00:00 2001 From: Alex Janka Date: Fri, 28 Apr 2023 12:43:37 +1000 Subject: [PATCH] webcam support is Better but not there loll --- Cargo.lock | 258 +++++++++++++++++++++++------------------ gb-emu/Cargo.toml | 2 +- gb-emu/src/camera.rs | 71 ++++++++++-- gb-emu/src/debug.rs | 11 +- gb-emu/src/main.rs | 79 ++++++++----- gb-vst/src/lib.rs | 6 +- lib/src/connect/mod.rs | 32 +++-- lib/src/lib.rs | 123 +++++++++++--------- 8 files changed, 343 insertions(+), 239 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 5e1236f..99919ef 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -44,15 +44,6 @@ dependencies = [ "version_check", ] -[[package]] -name = "aho-corasick" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67fc08ce920c31afb70f013dcce1bfc3a3195de6a228474e45e1f145b36f8d04" -dependencies = [ - "memchr", -] - [[package]] name = "alsa" version = "0.7.0" @@ -237,7 +228,7 @@ checksum = "233d376d6d185f2a3093e58f283f60f880315b6c60075b01f36b3b85154564ca" dependencies = [ "addr2line", "cc", - "cfg-if", + "cfg-if 1.0.0", "libc", "miniz_oxide 0.6.2", "object", @@ -254,8 +245,8 @@ checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8" name = "baseview" version = "0.1.0" dependencies = [ - "cocoa", - "core-foundation", + "cocoa 0.24.1", + "core-foundation 0.9.3", "keyboard-types", "nix 0.22.3", "objc", @@ -400,6 +391,12 @@ dependencies = [ "nom", ] +[[package]] +name = "cfg-if" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822" + [[package]] name = "cfg-if" version = "1.0.0" @@ -425,16 +422,6 @@ dependencies = [ "winapi", ] -[[package]] -name = "clang" -version = "2.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "84c044c781163c001b913cd018fc95a628c50d0d2dfea8bca77dad71edb16e37" -dependencies = [ - "clang-sys", - "libc", -] - [[package]] name = "clang-sys" version = "1.6.1" @@ -494,6 +481,21 @@ version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8a2dd5a6fe8c6e3502f568a6353e5273bbb15193ad9a89e457b9970798efbea1" +[[package]] +name = "cocoa" +version = "0.20.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c49e86fc36d5704151f5996b7b3795385f50ce09e3be0f47a0cfde869681cf8" +dependencies = [ + "bitflags", + "block", + "core-foundation 0.7.0", + "core-graphics 0.19.2", + "foreign-types", + "libc", + "objc", +] + [[package]] name = "cocoa" version = "0.24.1" @@ -503,8 +505,8 @@ dependencies = [ "bitflags", "block", "cocoa-foundation", - "core-foundation", - "core-graphics", + "core-foundation 0.9.3", + "core-graphics 0.22.3", "foreign-types", "libc", "objc", @@ -518,7 +520,7 @@ checksum = "931d3837c286f56e3c58423ce4eba12d08db2374461a785c86f672b08b5650d6" dependencies = [ "bitflags", "block", - "core-foundation", + "core-foundation 0.9.3", "core-graphics-types", "foreign-types", "libc", @@ -563,6 +565,16 @@ dependencies = [ "memchr", ] +[[package]] +name = "core-foundation" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57d24c7a13c43e870e37c1556b74555437870a04514f7685f5b354e090567171" +dependencies = [ + "core-foundation-sys 0.7.0", + "libc", +] + [[package]] name = "core-foundation" version = "0.9.3" @@ -579,12 +591,30 @@ version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e7ca8a5221364ef15ce201e8ed2f609fc312682a8f4e0e3d4aa5879764e0fa3b" +[[package]] +name = "core-foundation-sys" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b3a71ab494c0b5b860bdc8407ae08978052417070c2ced38573a9157ad75b8ac" + [[package]] name = "core-foundation-sys" version = "0.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e496a50fda8aacccc86d7529e2c1e0892dbd0f898a6b5645b5561b89c3210efa" +[[package]] +name = "core-graphics" +version = "0.19.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b3889374e6ea6ab25dba90bb5d96202f61108058361f6dc72e8b03e6f8bbe923" +dependencies = [ + "bitflags", + "core-foundation 0.7.0", + "foreign-types", + "libc", +] + [[package]] name = "core-graphics" version = "0.22.3" @@ -592,7 +622,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2581bbab3b8ffc6fcbd550bf46c355135d16e9ff2a6ea032ad6b9bf1d7efe4fb" dependencies = [ "bitflags", - "core-foundation", + "core-foundation 0.9.3", "core-graphics-types", "foreign-types", "libc", @@ -605,11 +635,36 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3a68b68b3446082644c91ac778bf50cd4104bfb002b5a6a7c44cca5a2c70788b" dependencies = [ "bitflags", - "core-foundation", + "core-foundation 0.9.3", "foreign-types", "libc", ] +[[package]] +name = "core-media-sys" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "273bf3fc5bf51fd06a7766a84788c1540b6527130a0bce39e00567d6ab9f31f1" +dependencies = [ + "cfg-if 0.1.10", + "core-foundation-sys 0.7.0", + "libc", +] + +[[package]] +name = "core-video-sys" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34ecad23610ad9757664d644e369246edde1803fcb43ed72876565098a5d3828" +dependencies = [ + "cfg-if 0.1.10", + "core-foundation-sys 0.7.0", + "core-graphics 0.19.2", + "libc", + "metal 0.18.0", + "objc", +] + [[package]] name = "coreaudio-rs" version = "0.11.2" @@ -636,7 +691,7 @@ version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1a7847ca018a67204508b77cb9e6de670125075f7464fff5f673023378fa34f5" dependencies = [ - "core-foundation", + "core-foundation 0.9.3", "core-foundation-sys 0.8.4", "coremidi-sys", ] @@ -681,7 +736,7 @@ version = "1.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b540bd8bc810d3885c6ea91e2018302f68baba2129ab3e88f32389ee9370880d" dependencies = [ - "cfg-if", + "cfg-if 1.0.0", ] [[package]] @@ -690,7 +745,7 @@ version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2801af0d36612ae591caa9568261fddce32ce6e08a7275ea334a06a4ad021a2c" dependencies = [ - "cfg-if", + "cfg-if 1.0.0", "crossbeam-channel", "crossbeam-deque", "crossbeam-epoch", @@ -704,7 +759,7 @@ version = "0.5.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a33c2bf77f2df06183c3aa30d1e96c0695a313d4f9c453cc3762a6db39f99200" dependencies = [ - "cfg-if", + "cfg-if 1.0.0", "crossbeam-utils", ] @@ -714,7 +769,7 @@ version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ce6fd6f855243022dcecf8702fef0c297d4338e226845fe067f6341ad9fa0cef" dependencies = [ - "cfg-if", + "cfg-if 1.0.0", "crossbeam-epoch", "crossbeam-utils", ] @@ -726,7 +781,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "46bd5f3f85273295a9d14aedfb86f6aadbff6d8f5295c4a9edb08e819dcf5695" dependencies = [ "autocfg", - "cfg-if", + "cfg-if 1.0.0", "crossbeam-utils", "memoffset 0.8.0", "scopeguard", @@ -738,7 +793,7 @@ version = "0.3.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d1cfb3ea8a53f37c40dea2c7bedcbd88bdfae54f5e2175d6ecaff1c988353add" dependencies = [ - "cfg-if", + "cfg-if 1.0.0", "crossbeam-utils", ] @@ -748,7 +803,7 @@ version = "0.8.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3c063cd8cc95f5c377ed0d4b49a4b21f632396ff690e8470c29b3359b346984b" dependencies = [ - "cfg-if", + "cfg-if 1.0.0", ] [[package]] @@ -1111,7 +1166,7 @@ version = "0.2.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c85e1d9ab2eadba7e5040d4e09cbd6d072b76a557ad64e797c2cb9d4da21d7e4" dependencies = [ - "cfg-if", + "cfg-if 1.0.0", "js-sys", "libc", "wasi", @@ -1137,7 +1192,7 @@ version = "0.5.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fd745b0cb1a207756e8fabacf5623066ad6aa543ea0be4bab34e897e6bbe24f9" dependencies = [ - "core-foundation", + "core-foundation 0.9.3", "io-kit-sys", "js-sys", "libc", @@ -1367,7 +1422,7 @@ version = "0.1.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c" dependencies = [ - "cfg-if", + "cfg-if 1.0.0", "js-sys", "wasm-bindgen", "web-sys", @@ -1546,7 +1601,7 @@ version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b67380fd3b2fbe7527a606e18729d21c6f3951633d0500574c4dc22d2d638b9f" dependencies = [ - "cfg-if", + "cfg-if 1.0.0", "winapi", ] @@ -1591,7 +1646,7 @@ version = "0.4.17" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "abb12e687cfb44aa40f41fc3978ef76448f9b6038cad6aef4259d3c095a2382e" dependencies = [ - "cfg-if", + "cfg-if 1.0.0", ] [[package]] @@ -1612,12 +1667,6 @@ dependencies = [ "libc", ] -[[package]] -name = "maplit" -version = "1.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3e2e65a1a2e43cfcb47a895c4c8b10d1f4a61097f9f254f183aee60cad9c651d" - [[package]] name = "memchr" version = "2.5.0" @@ -1651,6 +1700,21 @@ dependencies = [ "autocfg", ] +[[package]] +name = "metal" +version = "0.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e198a0ee42bdbe9ef2c09d0b9426f3b2b47d90d93a4a9b0395c4cea605e92dc0" +dependencies = [ + "bitflags", + "block", + "cocoa 0.20.2", + "core-graphics 0.19.2", + "foreign-types", + "log", + "objc", +] + [[package]] name = "metal" version = "0.24.0" @@ -1857,10 +1921,10 @@ dependencies = [ "backtrace", "baseview", "bitflags", - "cfg-if", + "cfg-if 1.0.0", "clap", "clap-sys", - "core-foundation", + "core-foundation 0.9.3", "cpal", "crossbeam", "jack", @@ -1910,7 +1974,7 @@ checksum = "e4916f159ed8e5de0082076562152a76b7a1f64a01fd9d1e0fea002c37624faf" dependencies = [ "bitflags", "cc", - "cfg-if", + "cfg-if 1.0.0", "libc", "memoffset 0.6.5", ] @@ -1922,7 +1986,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fa52e972a9a719cecb6864fb88568781eb706bac2cd1d4f04a648542dbf78069" dependencies = [ "bitflags", - "cfg-if", + "cfg-if 1.0.0", "libc", "memoffset 0.6.5", ] @@ -1935,7 +1999,7 @@ checksum = "f346ff70e7dbfd675fe90590b92d59ef2de15a8779ae305ebcbfd3f0caf59be4" dependencies = [ "autocfg", "bitflags", - "cfg-if", + "cfg-if 1.0.0", "libc", "memoffset 0.6.5", ] @@ -1947,7 +2011,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bfdda3d196821d6af13126e40375cdf7da646a96114af134d5f417a9a1dc8e1a" dependencies = [ "bitflags", - "cfg-if", + "cfg-if 1.0.0", "libc", "static_assertions", ] @@ -1960,13 +2024,28 @@ checksum = "143c7e68ab35542605825430efb8acaf977de40d4256ebfeed6324b35a6ba89a" dependencies = [ "flume", "image", + "nokhwa-bindings-macos", "nokhwa-core", - "opencv", "paste", - "rgb", "thiserror", ] +[[package]] +name = "nokhwa-bindings-macos" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5cb2044194c8cc0286a0bfae023caeb434c32900ffe3f3d08565362306437be8" +dependencies = [ + "block", + "cocoa-foundation", + "core-media-sys", + "core-video-sys", + "flume", + "nokhwa-core", + "objc", + "once_cell", +] + [[package]] name = "nokhwa-core" version = "0.1.0" @@ -1976,7 +2055,6 @@ dependencies = [ "bytes", "image", "mozjpeg", - "opencv", "thiserror", ] @@ -2144,49 +2222,13 @@ version = "1.17.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b7e5500299e16ebb147ae15a00a942af264cf3688f47923b8fc2cd5858f23ad3" -[[package]] -name = "opencv" -version = "0.74.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "33bd2442759725e3ce38862b32acb1999de51e9f3f4310f3b01b7f0623091d74" -dependencies = [ - "cc", - "clang", - "dunce", - "jobserver", - "libc", - "num-traits", - "once_cell", - "opencv-binding-generator", - "pkg-config", - "rgb", - "semver", - "shlex", - "vcpkg", -] - -[[package]] -name = "opencv-binding-generator" -version = "0.52.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "082d8259f4a7ea455e3553f9a1bc817520eb465a153bbf5ec0cb0b73590ee28d" -dependencies = [ - "clang", - "clang-sys", - "dunce", - "maplit", - "once_cell", - "percent-encoding", - "regex", -] - [[package]] name = "orbclient" version = "0.3.44" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0e9829e16c5e112e94efb5e2ad1fe17f8c1c99bb0fcdc8c65c44e935d904767d" dependencies = [ - "cfg-if", + "cfg-if 1.0.0", "redox_syscall 0.2.16", "wasm-bindgen", "web-sys", @@ -2217,7 +2259,7 @@ version = "0.9.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9069cbb9f99e3a5083476ccb29ceb1de18b9118cafa53e90c9551235de2b9521" dependencies = [ - "cfg-if", + "cfg-if 1.0.0", "libc", "redox_syscall 0.2.16", "smallvec", @@ -2448,8 +2490,6 @@ version = "1.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "af83e617f331cc6ae2da5443c602dfa5af81e517212d9d611a5b3ba1777b5370" dependencies = [ - "aho-corasick", - "memchr", "regex-syntax", ] @@ -2593,12 +2633,6 @@ dependencies = [ "tiny-skia", ] -[[package]] -name = "semver" -version = "1.0.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bebd363326d05ec3e2f532ab7660680f3b02130d780c299bca73469d521bc0ed" - [[package]] name = "send_wrapper" version = "0.6.0" @@ -2864,7 +2898,7 @@ dependencies = [ "arrayref", "arrayvec", "bytemuck", - "cfg-if", + "cfg-if 1.0.0", "png", "tiny-skia-path", ] @@ -2974,12 +3008,6 @@ version = "1.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5b55a3fef2a1e3b3a00ce878640918820d3c51081576ac657d23af9fc7928fdb" -[[package]] -name = "vcpkg" -version = "0.2.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" - [[package]] name = "vec_map" version = "0.8.2" @@ -3064,7 +3092,7 @@ version = "0.2.84" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "31f8dcbc21f30d9b8f2ea926ecb58f6b91192c17e9d33594b3df58b2007ca53b" dependencies = [ - "cfg-if", + "cfg-if 1.0.0", "wasm-bindgen-macro", ] @@ -3089,7 +3117,7 @@ version = "0.4.34" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f219e0d211ba40266969f6dbdd90636da12f75bee4fc9d6c23d1260dadb51454" dependencies = [ - "cfg-if", + "cfg-if 1.0.0", "js-sys", "wasm-bindgen", "web-sys", @@ -3236,7 +3264,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d745a1b6d91d85c33defbb29f0eee0450e1d2614d987e14bf6baf26009d132d7" dependencies = [ "arrayvec", - "cfg-if", + "cfg-if 1.0.0", "js-sys", "log", "naga 0.11.0", @@ -3323,7 +3351,7 @@ dependencies = [ "khronos-egl", "libloading", "log", - "metal", + "metal 0.24.0", "naga 0.10.0", "objc", "parking_lot", @@ -3365,7 +3393,7 @@ dependencies = [ "libc", "libloading", "log", - "metal", + "metal 0.24.0", "naga 0.11.0", "objc", "parking_lot", @@ -3637,8 +3665,8 @@ dependencies = [ "android-activity", "bitflags", "cfg_aliases", - "core-foundation", - "core-graphics", + "core-foundation 0.9.3", + "core-graphics 0.22.3", "dispatch", "instant", "libc", diff --git a/gb-emu/Cargo.toml b/gb-emu/Cargo.toml index 8e381eb..53657cf 100644 --- a/gb-emu/Cargo.toml +++ b/gb-emu/Cargo.toml @@ -14,7 +14,7 @@ gilrs = "0.10" cpal = "0.15" futures = "0.3" ctrlc = "3.2.5" -nokhwa = { version = "0.10.3", features = ["input-opencv"], optional = true } +nokhwa = { version = "0.10.3", features = ["input-avfoundation"], optional = true } send_wrapper = { version = "0.6.0", optional = true } winit = "0.28" winit_input_helper = "0.14" diff --git a/gb-emu/src/camera.rs b/gb-emu/src/camera.rs index 8167435..c8f481c 100644 --- a/gb-emu/src/camera.rs +++ b/gb-emu/src/camera.rs @@ -8,40 +8,95 @@ use send_wrapper::SendWrapper; pub struct Webcam { camera: SendWrapper, - buffer: [u8; 128 * 128], + scaled_buffer: [u8; 128 * 128], } impl Webcam { pub fn new() -> Self { - let format = RequestedFormat::new::( + let format = RequestedFormat::new::( RequestedFormatType::AbsoluteHighestResolution, ); + let mut camera = SendWrapper::new( + Camera::new(CameraIndex::Index(0), format).expect("Couldn't open camera"), + ); + camera + .set_frame_format(nokhwa::utils::FrameFormat::YUYV) + .expect("couldnt set frame format to yuyv"); + + if let Ok(formats) = camera.compatible_fourcc() { + if formats.is_empty() { + println!("no compatible frame formats listed"); + } + for f in formats { + println!("compatible frame format: {f:?}"); + } + } else { + println!("couldnt get frame formats") + } + + println!("current camera format: {:?}", camera.camera_format()); + + if let Ok(formats) = camera.compatible_camera_formats() { + if formats.is_empty() { + println!("camera formats is empty"); + } + for f in formats { + println!("supports camera format {f:?}"); + } + } else { + println!("couldnt get camera formats"); + } + Self { - camera: SendWrapper::new(Camera::new(CameraIndex::Index(0), format).unwrap()), - buffer: [0; 128 * 128], + camera, + scaled_buffer: [0; 128 * 128], } } } impl PocketCamera for Webcam { fn get_image(&mut self) -> [u8; 128 * 128] { - self.buffer + self.scaled_buffer } fn begin_capture(&mut self) { - let height = self.camera.resolution().height() as usize; + let _height = self.camera.resolution().height() as usize; let width = self.camera.resolution().width() as usize; - let frame = self.camera.frame_raw().expect("couldn't get frame"); + // let frame = self.camera.frame_raw().expect("couldn't get frame"); + self.camera + .set_frame_format(nokhwa::utils::FrameFormat::RAWRGB) + .unwrap(); + let frame = self.camera.frame().expect("couldn't get frame"); + println!("source format: {:?}", frame.source_frame_format()); + + let decoded = frame + .decode_image::() + .expect("couldn't decode image"); + let pixels = decoded.pixels().collect::>(); for y in 0..128 { for x in 0..128 { - self.buffer[y * 128 + x] = frame[((y * width) + x) * 2]; + self.scaled_buffer[y * 128 + x] = pixels[((y * width) + x) * 2][0]; } } } fn init(&mut self) { self.camera.open_stream().expect("couldn't open stream"); + self.camera + .set_frame_format(nokhwa::utils::FrameFormat::YUYV) + .unwrap(); + + println!( + "opened stream! current format: {:?}", + self.camera.camera_format() + ); + // let format = RequestedFormat::new::( + // RequestedFormatType::AbsoluteHighestResolution, + // ); + // self.camera + // .set_camera_requset(format) + // .expect("couldn't set format again"); } } diff --git a/gb-emu/src/debug.rs b/gb-emu/src/debug.rs index ada6c62..aa7f30c 100644 --- a/gb-emu/src/debug.rs +++ b/gb-emu/src/debug.rs @@ -1,7 +1,4 @@ -use gb_emu_lib::{ - connect::{EmulatorMessage, NoCamera}, - EmulatorCore, -}; +use gb_emu_lib::connect::{EmulatorCoreTrait, EmulatorMessage}; use std::{ collections::HashMap, io::{self, Write}, @@ -9,8 +6,6 @@ use std::{ sync::mpsc::Receiver, }; -use crate::window::WindowRenderer; - pub enum CommandErr { InvalidCommand, InvalidArgument, @@ -52,7 +47,7 @@ impl FromStr for Commands { } pub struct Debugger { - core: EmulatorCore<[u8; 4], WindowRenderer, NoCamera>, + core: Box, debug_receiver: Receiver, stepping: bool, last_command: String, @@ -62,7 +57,7 @@ pub struct Debugger { impl Debugger { pub fn new( - core: EmulatorCore<[u8; 4], WindowRenderer, NoCamera>, + core: Box, debug_receiver: Receiver, ) -> Self { Self { diff --git a/gb-emu/src/main.rs b/gb-emu/src/main.rs index 2e795fc..b21ca47 100644 --- a/gb-emu/src/main.rs +++ b/gb-emu/src/main.rs @@ -5,7 +5,9 @@ use camera::Webcam; use clap::{ArgGroup, Parser}; use debug::Debugger; use gb_emu_lib::{ - connect::{EmulatorMessage, EmulatorOptions, NoCamera, RomFile, SerialTarget}, + connect::{ + EmulatorCoreTrait, EmulatorMessage, EmulatorOptions, NoCamera, RomFile, SerialTarget, + }, EmulatorCore, }; use gilrs::Gilrs; @@ -65,6 +67,9 @@ struct Args { /// Show BootROM #[arg(long)] show_bootrom: bool, + // /// Use webcam as Pocket Camera emulation + // #[arg(short, long)] + // camera: bool, } fn main() { @@ -93,38 +98,54 @@ fn main() { let (output, _stream) = audio::create_output(args.mute); - #[cfg(feature = "webcam")] - let camera = Webcam::new(); - #[cfg(not(feature = "webcam"))] - let camera = NoCamera::default(); + let window = WindowRenderer::new(factor, Some(Gilrs::new().unwrap())); + let rom = RomFile::Path(args.rom); - let options = EmulatorOptions::new_with_camera( - WindowRenderer::new(factor, Some(Gilrs::new().unwrap())), - RomFile::Path(args.rom), - output, - camera, - ) - .with_save_path(args.save) - .with_serial_target(if args.connect_serial { - SerialTarget::Stdout + let options = EmulatorOptions::new(window, rom, output) + .with_save_path(args.save) + .with_serial_target(if args.connect_serial { + SerialTarget::Stdout + } else { + SerialTarget::None + }) + .with_bootrom(args.bootrom.map(RomFile::Path), args.show_bootrom) + .with_no_save(args.no_save) + .with_tile_window(tile_window) + .with_cgb_mode(!args.dmg); + + // let core: Box = if args.camera { + // Box::new(EmulatorCore::init(receiver, options, Webcam::new())) + // } else { + // Box::new(EmulatorCore::init(receiver, options, NoCamera::default())) + // }; + + #[cfg(not(feature = "camera"))] + let core: Box = + Box::new(EmulatorCore::init(receiver, options, NoCamera::default())); + #[cfg(feature = "camera")] + let core = Box::new(EmulatorCore::init(receiver, options, Webcam::new())); + + let mut handler = if args.debug { + EmulatorHandler::Debug(Debugger::new(core, debug_receiver)) } else { - SerialTarget::None - }) - .with_bootrom(args.bootrom.map(RomFile::Path), args.show_bootrom) - .with_no_save(args.no_save) - .with_tile_window(tile_window) - .with_cgb_mode(!args.dmg); + EmulatorHandler::Normal(core) + }; - let mut core = EmulatorCore::init(receiver, options); + loop { + handler.run(); + } +} - if args.debug { - let mut debugger = Debugger::new(core, debug_receiver); - loop { - debugger.step(); - } - } else { - loop { - core.run(); +enum EmulatorHandler { + Debug(Debugger), + Normal(Box), +} + +impl EmulatorHandler { + fn run(&mut self) { + match self { + EmulatorHandler::Debug(ref mut debugger) => debugger.step(), + EmulatorHandler::Normal(ref mut core) => core.run(), } } } diff --git a/gb-vst/src/lib.rs b/gb-vst/src/lib.rs index 1d3ee0c..75011e0 100644 --- a/gb-vst/src/lib.rs +++ b/gb-vst/src/lib.rs @@ -2,8 +2,8 @@ use async_ringbuf::AsyncHeapConsumer; use futures::executor; use gb_emu_lib::{ connect::{ - AudioOutput, DownsampleType, EmulatorMessage, EmulatorOptions, JoypadButtons, NoCamera, - RomFile, SerialTarget, + AudioOutput, DownsampleType, EmulatorCoreTrait, EmulatorMessage, EmulatorOptions, + JoypadButtons, NoCamera, RomFile, SerialTarget, }, EmulatorCore, }; @@ -266,7 +266,7 @@ impl Plugin for GameboyEmu { .with_serial_target(serial_target) .force_no_save(); - EmulatorCore::init(receiver, options) + EmulatorCore::init(receiver, options, NoCamera::default()) }; emulator_core.run_until_buffer_full(); diff --git a/lib/src/connect/mod.rs b/lib/src/connect/mod.rs index d68ceac..a742c07 100644 --- a/lib/src/connect/mod.rs +++ b/lib/src/connect/mod.rs @@ -1,7 +1,7 @@ use std::marker::PhantomData; use std::sync::{Arc, Mutex}; -use crate::processor::memory::mmio::gpu::Colour; +pub use crate::processor::memory::mmio::gpu::Colour; pub use crate::processor::memory::mmio::joypad::{JoypadButtons, JoypadState}; pub use crate::processor::memory::mmio::serial::SerialTarget; pub use crate::processor::CpuSaveState; @@ -155,18 +155,17 @@ where } #[non_exhaustive] -pub struct EmulatorOptions +pub struct EmulatorOptions where ColourFormat: From + Clone, R: Renderer, - C: PocketCamera + Send + 'static, { pub(crate) window: R, pub(crate) tile_window: Option, pub(crate) rom: RomFile, pub(crate) output: AudioOutput, pub(crate) save_path: Option, - pub(crate) camera: C, + pub(crate) no_save: bool, pub(crate) bootrom: Option, pub(crate) show_bootrom: bool, @@ -175,30 +174,18 @@ where spooky: PhantomData, } -impl EmulatorOptions +impl EmulatorOptions where ColourFormat: From + Clone, R: Renderer, { pub fn new(window: R, rom: RomFile, output: AudioOutput) -> Self { - Self::new_with_camera(window, rom, output, NoCamera::default()) - } -} - -impl EmulatorOptions -where - ColourFormat: From + Clone, - R: Renderer, - C: PocketCamera + Send + 'static, -{ - pub fn new_with_camera(window: R, rom: RomFile, output: AudioOutput, camera: C) -> Self { Self { window, tile_window: None, rom, output, save_path: None, - camera, no_save: false, bootrom: None, show_bootrom: false, @@ -249,3 +236,14 @@ where self } } + +pub trait EmulatorCoreTrait { + fn replace_output(&mut self, new: AudioOutput); + fn cycle_count(&self) -> usize; + fn pc(&self) -> u16; + fn print_reg(&self) -> String; + fn get_memory(&self, address: u16) -> u8; + fn run(&mut self); + fn run_stepped(&mut self, step_size: usize); + fn run_until_buffer_full(&mut self); +} diff --git a/lib/src/lib.rs b/lib/src/lib.rs index e662403..456a861 100644 --- a/lib/src/lib.rs +++ b/lib/src/lib.rs @@ -5,8 +5,8 @@ use crate::{ util::pause, }; use connect::{ - AudioOutput, CameraWrapper, CameraWrapperRef, EmulatorMessage, EmulatorOptions, NoCamera, - PocketCamera, Renderer, RomFile, SerialTarget, + AudioOutput, CameraWrapper, CameraWrapperRef, EmulatorCoreTrait, EmulatorMessage, + EmulatorOptions, NoCamera, PocketCamera, Renderer, RomFile, SerialTarget, }; use processor::{ memory::{mmio::gpu::Colour, rom::CgbRomType, OutputTargets, Rom}, @@ -49,9 +49,10 @@ where { pub fn init( receiver: Receiver, - mut options: EmulatorOptions, + mut options: EmulatorOptions, + camera: C, ) -> Self { - let camera: CameraWrapperRef = Arc::new(Mutex::new(CameraWrapper::new(options.camera))); + let camera: CameraWrapperRef = Arc::new(Mutex::new(CameraWrapper::new(camera))); let rom = match options.rom { RomFile::Path(path) => { @@ -136,33 +137,6 @@ where } } - pub fn replace_output(&mut self, new: AudioOutput) { - self.cpu.memory.replace_output(new); - } - - pub fn cycle_count(&self) -> usize { - self.cpu.cycle_count - } - - pub fn pc(&self) -> u16 { - self.cpu.reg.pc - } - - pub fn print_reg(&self) -> String { - format!( - "A:{:0>2X}, F:{}, BC:{:0>4X}, DE:{:0>4X}, HL:{:0>4X}, SP:{:0>4X}, PC:{:0>4X}\nLast instruction: {:0>2X} from 0x{:0>4X}", - self.cpu.reg.get_8(processor::Reg8::A), - self.print_flags(), - self.cpu.reg.bc, - self.cpu.reg.de, - self.cpu.reg.hl, - self.cpu.reg.sp, - self.cpu.reg.pc, - self.cpu.last_instruction, - self.cpu.last_instruction_addr - ) - } - fn print_flags(&self) -> String { format!( "{}{}{}{}", @@ -189,32 +163,6 @@ where ) } - pub fn get_memory(&self, address: u16) -> u8 { - self.cpu.memory.get(address) - } - - pub fn run(&mut self) { - self.process_messages(); - self.run_cycle(); - } - - pub fn run_stepped(&mut self, step_size: usize) { - loop { - self.process_messages(); - for _ in 0..step_size { - self.run_cycle(); - } - stdout().flush().unwrap(); - pause(); - } - } - - pub fn run_until_buffer_full(&mut self) { - while !self.cpu.memory.is_audio_buffer_full() { - self.run(); - } - } - fn run_cycle(&mut self) { self.cpu.exec_next(); } @@ -229,7 +177,6 @@ where } } } - pub fn get_save_state(&self) -> CpuSaveState where ColourFormat: From + Clone, @@ -239,6 +186,66 @@ where } } +impl EmulatorCoreTrait for EmulatorCore +where + ColourFormat: From + Clone, + R: Renderer, + C: PocketCamera + Send + 'static, +{ + fn replace_output(&mut self, new: AudioOutput) { + self.cpu.memory.replace_output(new); + } + + fn cycle_count(&self) -> usize { + self.cpu.cycle_count + } + + fn pc(&self) -> u16 { + self.cpu.reg.pc + } + + fn print_reg(&self) -> String { + format!( + "A:{:0>2X}, F:{}, BC:{:0>4X}, DE:{:0>4X}, HL:{:0>4X}, SP:{:0>4X}, PC:{:0>4X}\nLast instruction: {:0>2X} from 0x{:0>4X}", + self.cpu.reg.get_8(processor::Reg8::A), + self.print_flags(), + self.cpu.reg.bc, + self.cpu.reg.de, + self.cpu.reg.hl, + self.cpu.reg.sp, + self.cpu.reg.pc, + self.cpu.last_instruction, + self.cpu.last_instruction_addr + ) + } + + fn get_memory(&self, address: u16) -> u8 { + self.cpu.memory.get(address) + } + + fn run(&mut self) { + self.process_messages(); + self.run_cycle(); + } + + fn run_stepped(&mut self, step_size: usize) { + loop { + self.process_messages(); + for _ in 0..step_size { + self.run_cycle(); + } + stdout().flush().unwrap(); + pause(); + } + } + + fn run_until_buffer_full(&mut self) { + while !self.cpu.memory.is_audio_buffer_full() { + self.run(); + } + } +} + impl EmulatorCore where ColourFormat: From + Clone,