Compare commits
No commits in common. "259503e505caa9ac15c1cc92e2976ac6de378e7f" and "ac4446b0551353f0f8bb00c27ca316d645c91791" have entirely different histories.
259503e505
...
ac4446b055
15 changed files with 621 additions and 932 deletions
1391
Cargo.lock
generated
1391
Cargo.lock
generated
File diff suppressed because it is too large
Load diff
|
@ -21,11 +21,11 @@ nokhwa = { version = "0.10", features = [
|
||||||
"input-avfoundation",
|
"input-avfoundation",
|
||||||
], optional = true }
|
], optional = true }
|
||||||
send_wrapper = { version = "0.6.0", optional = true }
|
send_wrapper = { version = "0.6.0", optional = true }
|
||||||
winit = { version = "0.29.15", features = ["rwh_05"] }
|
winit = { version = "0.29", features = ["rwh_05"] }
|
||||||
winit_input_helper = "0.16"
|
winit_input_helper = "0.15"
|
||||||
raw-window-handle = { workspace = true }
|
raw-window-handle = { workspace = true }
|
||||||
serde = { version = "1.0", features = ["derive"] }
|
serde = { version = "1.0", features = ["derive"] }
|
||||||
image = { version = "0.25.1", default-features = false, features = ["png"] }
|
image = { version = "0.24", default-features = false, features = ["png"] }
|
||||||
bytemuck = "1.14"
|
bytemuck = "1.14"
|
||||||
chrono = "0.4"
|
chrono = "0.4"
|
||||||
log = { workspace = true }
|
log = { workspace = true }
|
||||||
|
|
|
@ -3,7 +3,7 @@ use cpal::{
|
||||||
Stream,
|
Stream,
|
||||||
};
|
};
|
||||||
use futures::executor;
|
use futures::executor;
|
||||||
use gb_emu_lib::connect::{AsyncConsumer, AudioOutput, DownsampleType};
|
use gb_emu_lib::connect::{AudioOutput, DownsampleType};
|
||||||
|
|
||||||
use crate::access_config;
|
use crate::access_config;
|
||||||
|
|
||||||
|
|
|
@ -27,7 +27,7 @@ nih_plug = { workspace = true, features = [
|
||||||
"vst3",
|
"vst3",
|
||||||
], optional = true }
|
], optional = true }
|
||||||
baseview = { workspace = true, optional = true }
|
baseview = { workspace = true, optional = true }
|
||||||
async-ringbuf = { version = "0.2.1", optional = true }
|
async-ringbuf = { version = "0.1", optional = true }
|
||||||
futures = { version = "0.3", optional = true }
|
futures = { version = "0.3", optional = true }
|
||||||
keyboard-types = { version = "0.6.2", optional = true }
|
keyboard-types = { version = "0.6.2", optional = true }
|
||||||
raw-window-handle = { workspace = true }
|
raw-window-handle = { workspace = true }
|
||||||
|
|
|
@ -1,7 +1,4 @@
|
||||||
use async_ringbuf::{
|
use async_ringbuf::AsyncHeapConsumer;
|
||||||
traits::{AsyncConsumer, Observer},
|
|
||||||
AsyncHeapCons,
|
|
||||||
};
|
|
||||||
use baseview::Size;
|
use baseview::Size;
|
||||||
use futures::executor;
|
use futures::executor;
|
||||||
use gb_emu_lib::{
|
use gb_emu_lib::{
|
||||||
|
@ -54,7 +51,7 @@ struct EmuParams {
|
||||||
}
|
}
|
||||||
|
|
||||||
struct EmuVars {
|
struct EmuVars {
|
||||||
rx: AsyncHeapCons<[f32; 2]>,
|
rx: AsyncHeapConsumer<[f32; 2]>,
|
||||||
emulator_core: EmulatorCore<[u8; 4]>,
|
emulator_core: EmulatorCore<[u8; 4]>,
|
||||||
serial_tx: Sender<u8>,
|
serial_tx: Sender<u8>,
|
||||||
}
|
}
|
||||||
|
@ -327,7 +324,6 @@ impl Plugin for GameboyEmu {
|
||||||
.with_show_bootrom(!will_skip_bootrom);
|
.with_show_bootrom(!will_skip_bootrom);
|
||||||
|
|
||||||
EmulatorCore::init(false, receiver, options)
|
EmulatorCore::init(false, receiver, options)
|
||||||
.expect("couldn't initialize emulator core!")
|
|
||||||
};
|
};
|
||||||
|
|
||||||
emulator_core.run_until_buffer_full();
|
emulator_core.run_until_buffer_full();
|
||||||
|
|
|
@ -9,19 +9,19 @@ identifier = "com.alexjanka.TWINC.gui"
|
||||||
osx_file_extensions = [[["Game Boy ROM", "Viewer"], ["gb", "gbc"]]]
|
osx_file_extensions = [[["Game Boy ROM", "Viewer"], ["gb", "gbc"]]]
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
default = ["macos-ui", "crossplatform-ui"]
|
default = ["macos-ui", "crossplatform-ui", "force-crossplatform-ui"]
|
||||||
macos-ui = ["cacao", "objc", "uuid"]
|
macos-ui = ["cacao", "objc", "uuid"]
|
||||||
crossplatform-ui = ["gtk", "adw", "glib-build-tools"]
|
crossplatform-ui = ["gtk", "adw", "glib-build-tools"]
|
||||||
force-crossplatform-ui = ["crossplatform-ui"]
|
force-crossplatform-ui = ["crossplatform-ui"]
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
adw = { version = "0.7.0", package = "libadwaita", features = [
|
adw = { version = "0.6.0", package = "libadwaita", features = [
|
||||||
"v1_4",
|
"v1_4",
|
||||||
"gtk_v4_6",
|
"gtk_v4_12",
|
||||||
], optional = true }
|
], optional = true }
|
||||||
frontend-common = { workspace = true }
|
frontend-common = { workspace = true }
|
||||||
gb-emu-lib = { workspace = true }
|
gb-emu-lib = { workspace = true }
|
||||||
gtk = { version = "0.9.0", package = "gtk4", features = [
|
gtk = { version = "0.8.0", package = "gtk4", features = [
|
||||||
"v4_12",
|
"v4_12",
|
||||||
], optional = true }
|
], optional = true }
|
||||||
twinc_emu_vst = { path = "../gb-vst", default-features = false }
|
twinc_emu_vst = { path = "../gb-vst", default-features = false }
|
||||||
|
@ -40,4 +40,4 @@ uuid = { version = "1.6", features = ["v4", "fast-rng"], optional = true }
|
||||||
|
|
||||||
|
|
||||||
[build-dependencies]
|
[build-dependencies]
|
||||||
glib-build-tools = { version = "0.20.0", optional = true }
|
glib-build-tools = { version = "0.19.0", optional = true }
|
||||||
|
|
|
@ -301,14 +301,7 @@ impl CacaoWindowManager {
|
||||||
if state {
|
if state {
|
||||||
let is_running = self.is_emulator_running();
|
let is_running = self.is_emulator_running();
|
||||||
if is_running {
|
if is_running {
|
||||||
let new_layer_window: Sender<RendererMessage<[u8; 4]>> =
|
let new_layer_window = new_layer_window(self);
|
||||||
match new_layer_window(self) {
|
|
||||||
Ok(t) => t,
|
|
||||||
Err(e) => {
|
|
||||||
log::error!("couldn't create tile window: {e:?}");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
if let Some(ref handles) = self.handles {
|
if let Some(ref handles) = self.handles {
|
||||||
handles
|
handles
|
||||||
.sender
|
.sender
|
||||||
|
@ -323,13 +316,7 @@ impl CacaoWindowManager {
|
||||||
if state {
|
if state {
|
||||||
let is_running = self.is_emulator_running();
|
let is_running = self.is_emulator_running();
|
||||||
if is_running {
|
if is_running {
|
||||||
let new_tile_window = match new_tile_window(self) {
|
let new_tile_window = new_tile_window(self);
|
||||||
Ok(t) => t,
|
|
||||||
Err(e) => {
|
|
||||||
log::error!("couldn't create tile window: {e:?}");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
if let Some(ref handles) = self.handles {
|
if let Some(ref handles) = self.handles {
|
||||||
handles
|
handles
|
||||||
.sender
|
.sender
|
||||||
|
|
|
@ -170,13 +170,7 @@ impl Dispatcher for TwincUiApp {
|
||||||
let (output, stream) = audio::create_output(false);
|
let (output, stream) = audio::create_output(false);
|
||||||
let mut window_manager = self.current_game.write().unwrap();
|
let mut window_manager = self.current_game.write().unwrap();
|
||||||
window_manager.update_handles(sender, stream);
|
window_manager.update_handles(sender, stream);
|
||||||
let mut core = match frontend_common::run(prepared, &mut *window_manager, output) {
|
let mut core = frontend_common::run(prepared, &mut *window_manager, output);
|
||||||
Ok(c) => c,
|
|
||||||
Err(e) => {
|
|
||||||
log::error!("couldn't create emulator core: {e:?}");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
let handle = std::thread::Builder::new()
|
let handle = std::thread::Builder::new()
|
||||||
.name(String::from("EmuCore"))
|
.name(String::from("EmuCore"))
|
||||||
.spawn(move || loop {
|
.spawn(move || loop {
|
||||||
|
|
|
@ -4,7 +4,6 @@ use std::path::PathBuf;
|
||||||
|
|
||||||
use cacao::button::Button;
|
use cacao::button::Button;
|
||||||
use cacao::filesystem::FileSelectPanel;
|
use cacao::filesystem::FileSelectPanel;
|
||||||
use cacao::image::{Image, ImageView};
|
|
||||||
use cacao::input::TextField;
|
use cacao::input::TextField;
|
||||||
use cacao::layout::{Layout, LayoutConstraint};
|
use cacao::layout::{Layout, LayoutConstraint};
|
||||||
use cacao::select::Select;
|
use cacao::select::Select;
|
||||||
|
@ -206,7 +205,7 @@ pub struct PickerView<T>
|
||||||
where
|
where
|
||||||
T: ToString,
|
T: ToString,
|
||||||
{
|
{
|
||||||
pub _view: View,
|
pub view: View,
|
||||||
pub select: Select,
|
pub select: Select,
|
||||||
pub title: Label,
|
pub title: Label,
|
||||||
_p: PhantomData<T>,
|
_p: PhantomData<T>,
|
||||||
|
@ -244,7 +243,7 @@ where
|
||||||
]);
|
]);
|
||||||
|
|
||||||
Self {
|
Self {
|
||||||
_view: view,
|
view,
|
||||||
select,
|
select,
|
||||||
title,
|
title,
|
||||||
_p: PhantomData,
|
_p: PhantomData,
|
||||||
|
@ -486,43 +485,3 @@ impl StepperViewToggle {
|
||||||
self.enabled = !self.enabled;
|
self.enabled = !self.enabled;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct ImageViewWrapper {
|
|
||||||
view: View,
|
|
||||||
image_view: ImageView,
|
|
||||||
_image: Image,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl ImageViewWrapper {
|
|
||||||
pub fn new(image: Image) -> Self {
|
|
||||||
let view = View::new();
|
|
||||||
let image_view = ImageView::new();
|
|
||||||
image_view.set_image(&image);
|
|
||||||
view.add_subview(&image_view);
|
|
||||||
|
|
||||||
LayoutConstraint::activate(&[
|
|
||||||
image_view
|
|
||||||
.leading
|
|
||||||
.constraint_equal_to(&view.leading)
|
|
||||||
.offset(10.),
|
|
||||||
image_view.top.constraint_equal_to(&view.top).offset(10.),
|
|
||||||
image_view
|
|
||||||
.bottom
|
|
||||||
.constraint_equal_to(&view.bottom)
|
|
||||||
.offset(-10.),
|
|
||||||
]);
|
|
||||||
Self {
|
|
||||||
view,
|
|
||||||
image_view,
|
|
||||||
_image: image,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn view(&self) -> &View {
|
|
||||||
&self.view
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn image_view(&self) -> &ImageView {
|
|
||||||
&self.image_view
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -4,7 +4,7 @@ version = "0.5.1"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
default = ["config", "librashader", "wgpu-renderer"]
|
default = []
|
||||||
clocked-serial = []
|
clocked-serial = []
|
||||||
librashader = [
|
librashader = [
|
||||||
"dep:librashader",
|
"dep:librashader",
|
||||||
|
@ -34,9 +34,9 @@ error-colour = []
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
rand = "0.8.5"
|
rand = "0.8.5"
|
||||||
async-ringbuf = "0.2.1"
|
async-ringbuf = "0.1"
|
||||||
futures = "0.3.30"
|
futures = "0.3"
|
||||||
itertools = "0.13.0"
|
itertools = "0.12"
|
||||||
serde = { version = "1.0", features = ["derive"] }
|
serde = { version = "1.0", features = ["derive"] }
|
||||||
serde_with = "3.0"
|
serde_with = "3.0"
|
||||||
bytemuck = "1.14"
|
bytemuck = "1.14"
|
||||||
|
@ -51,16 +51,13 @@ librashader-common = { workspace = true, optional = true }
|
||||||
directories = { version = "5.0", optional = true }
|
directories = { version = "5.0", optional = true }
|
||||||
ron = { version = "0.8", optional = true }
|
ron = { version = "0.8", optional = true }
|
||||||
lazy_static = "1.4"
|
lazy_static = "1.4"
|
||||||
wgpu = { version = "22.0.0", optional = true }
|
wgpu = { version = "0.20", optional = true }
|
||||||
thiserror = { workspace = true }
|
thiserror = { workspace = true }
|
||||||
log = { workspace = true }
|
log = { workspace = true }
|
||||||
anyhow = "1.0.86"
|
anyhow = "1.0.86"
|
||||||
|
|
||||||
[build-dependencies]
|
[build-dependencies]
|
||||||
naga = { version = "22.0.0", optional = true, features = [
|
naga = { version = "0.19", optional = true, features = ["wgsl-in", "spv-out"] }
|
||||||
"wgsl-in",
|
|
||||||
"spv-out",
|
|
||||||
] }
|
|
||||||
|
|
||||||
[target.'cfg(any(target_os = "macos", target_os = "ios"))'.dependencies]
|
[target.'cfg(any(target_os = "macos", target_os = "ios"))'.dependencies]
|
||||||
ash-molten = { version = "0.19.0", optional = true }
|
ash-molten = { version = "0.16.0", optional = true }
|
||||||
|
|
|
@ -1,11 +1,8 @@
|
||||||
use async_ringbuf::{traits::Split, AsyncHeapCons, AsyncHeapProd, AsyncHeapRb};
|
|
||||||
use std::fs;
|
use std::fs;
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
use std::sync::mpsc::Sender;
|
use std::sync::mpsc::Sender;
|
||||||
use std::sync::{Arc, RwLock};
|
use std::sync::{Arc, RwLock};
|
||||||
|
|
||||||
pub use async_ringbuf::traits::consumer::AsyncConsumer;
|
|
||||||
|
|
||||||
pub use crate::error::RomHeaderError;
|
pub use crate::error::RomHeaderError;
|
||||||
pub 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::joypad::{JoypadButtons, JoypadState};
|
||||||
|
@ -16,6 +13,7 @@ pub use crate::processor::memory::rom::{
|
||||||
};
|
};
|
||||||
pub use crate::processor::memory::Rom;
|
pub use crate::processor::memory::Rom;
|
||||||
pub use crate::{HEIGHT, WIDTH};
|
pub use crate::{HEIGHT, WIDTH};
|
||||||
|
use async_ringbuf::{AsyncHeapConsumer, AsyncHeapProducer, AsyncHeapRb};
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum EmulatorMessage<ColourFormat>
|
pub enum EmulatorMessage<ColourFormat>
|
||||||
|
@ -100,7 +98,7 @@ pub struct ResolutionData {
|
||||||
|
|
||||||
pub struct AudioOutput {
|
pub struct AudioOutput {
|
||||||
pub sample_rate: f32,
|
pub sample_rate: f32,
|
||||||
pub send_rb: AsyncHeapProd<[f32; 2]>,
|
pub send_rb: AsyncHeapProducer<[f32; 2]>,
|
||||||
pub downsample_type: DownsampleType,
|
pub downsample_type: DownsampleType,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -109,7 +107,7 @@ impl AudioOutput {
|
||||||
sample_rate: f32,
|
sample_rate: f32,
|
||||||
buffers_per_frame: usize,
|
buffers_per_frame: usize,
|
||||||
downsample_type: DownsampleType,
|
downsample_type: DownsampleType,
|
||||||
) -> (Self, AsyncHeapCons<[f32; 2]>) {
|
) -> (Self, AsyncHeapConsumer<[f32; 2]>) {
|
||||||
let rb_len = (sample_rate as usize / 60) / buffers_per_frame;
|
let rb_len = (sample_rate as usize / 60) / buffers_per_frame;
|
||||||
|
|
||||||
let rb = AsyncHeapRb::<[f32; 2]>::new(rb_len);
|
let rb = AsyncHeapRb::<[f32; 2]>::new(rb_len);
|
||||||
|
|
|
@ -7,7 +7,6 @@ use crate::{
|
||||||
processor::memory::addresses::{AddressMarker, AudioAddress, WaveRamAddress},
|
processor::memory::addresses::{AddressMarker, AudioAddress, WaveRamAddress},
|
||||||
util::{get_bit, set_or_clear_bit},
|
util::{get_bit, set_or_clear_bit},
|
||||||
};
|
};
|
||||||
use async_ringbuf::traits::{AsyncProducer, Observer};
|
|
||||||
use futures::executor;
|
use futures::executor;
|
||||||
use itertools::izip;
|
use itertools::izip;
|
||||||
|
|
||||||
|
|
|
@ -97,7 +97,6 @@ impl RendererBackend for WgpuBackend {
|
||||||
required_features: wgpu::Features::ADDRESS_MODE_CLAMP_TO_BORDER,
|
required_features: wgpu::Features::ADDRESS_MODE_CLAMP_TO_BORDER,
|
||||||
required_limits: wgpu::Limits::default(),
|
required_limits: wgpu::Limits::default(),
|
||||||
label: None,
|
label: None,
|
||||||
memory_hints: wgpu::MemoryHints::default(),
|
|
||||||
},
|
},
|
||||||
None,
|
None,
|
||||||
)
|
)
|
||||||
|
|
|
@ -6,14 +6,14 @@ use gb_emu_lib::connect::{EmulatorCoreTrait, RomFile};
|
||||||
mod common;
|
mod common;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn cpu_instrs() -> anyhow::Result<()> {
|
fn cpu_instrs() -> Result<(), String> {
|
||||||
run_blargg_test("cpu_instrs\n\n01:ok 02:ok 03:ok 04:ok 05:ok 06:ok 07:ok 08:ok 09:ok 10:ok 11:ok \n\nPassed all tests", include_bytes!(
|
run_blargg_test("cpu_instrs\n\n01:ok 02:ok 03:ok 04:ok 05:ok 06:ok 07:ok 08:ok 09:ok 10:ok 11:ok \n\nPassed all tests", include_bytes!(
|
||||||
"../../test-roms/blargg/cpu_instrs/cpu_instrs.gb"
|
"../../test-roms/blargg/cpu_instrs/cpu_instrs.gb"
|
||||||
),None)
|
),None)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn instr_timing() -> anyhow::Result<()> {
|
fn instr_timing() -> Result<(), String> {
|
||||||
run_blargg_test(
|
run_blargg_test(
|
||||||
"instr_timing\n\n\nPassed",
|
"instr_timing\n\n\nPassed",
|
||||||
include_bytes!("../../test-roms/blargg/instr_timing/instr_timing.gb"),
|
include_bytes!("../../test-roms/blargg/instr_timing/instr_timing.gb"),
|
||||||
|
@ -22,7 +22,7 @@ fn instr_timing() -> anyhow::Result<()> {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn mem_timing() -> anyhow::Result<()> {
|
fn mem_timing() -> Result<(), String> {
|
||||||
run_blargg_test(
|
run_blargg_test(
|
||||||
"mem_timing\n\n\nPassed",
|
"mem_timing\n\n\nPassed",
|
||||||
include_bytes!("../../test-roms/blargg/mem_timing/mem_timing.gb"),
|
include_bytes!("../../test-roms/blargg/mem_timing/mem_timing.gb"),
|
||||||
|
@ -30,17 +30,11 @@ fn mem_timing() -> anyhow::Result<()> {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, thiserror::Error)]
|
|
||||||
enum TestError {
|
|
||||||
#[error("Timeout")]
|
|
||||||
Timeout(String),
|
|
||||||
}
|
|
||||||
|
|
||||||
fn run_blargg_test<const N: usize>(
|
fn run_blargg_test<const N: usize>(
|
||||||
correct_output: &str,
|
correct_output: &str,
|
||||||
rom: &[u8; N],
|
rom: &[u8; N],
|
||||||
extra_end: Option<Vec<&str>>,
|
extra_end: Option<Vec<&str>>,
|
||||||
) -> anyhow::Result<()> {
|
) -> Result<(), String> {
|
||||||
let mut emu = emulator_setup(RomFile::Raw(rom.to_vec()))?;
|
let mut emu = emulator_setup(RomFile::Raw(rom.to_vec()))?;
|
||||||
|
|
||||||
let mut end_strings = extra_end.unwrap_or_default();
|
let mut end_strings = extra_end.unwrap_or_default();
|
||||||
|
@ -60,7 +54,7 @@ fn run_blargg_test<const N: usize>(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if began.elapsed() > timeout {
|
if began.elapsed() > timeout {
|
||||||
return Err(TestError::Timeout(format!("Test timed out: output was {chars}")).into());
|
return Err(format!("Test timed out: output was {chars}"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
use std::sync::mpsc::{channel, Receiver, Sender};
|
use std::sync::mpsc::{channel, Receiver, Sender};
|
||||||
|
|
||||||
|
use async_ringbuf::AsyncHeapConsumer;
|
||||||
use gb_emu_lib::{
|
use gb_emu_lib::{
|
||||||
connect::{AudioOutput, EmulatorMessage, EmulatorOptions, RomFile},
|
connect::{AudioOutput, EmulatorMessage, EmulatorOptions, RomFile},
|
||||||
EmulatorCore,
|
EmulatorCore,
|
||||||
|
@ -7,14 +8,16 @@ use gb_emu_lib::{
|
||||||
|
|
||||||
pub struct TestEmulator {
|
pub struct TestEmulator {
|
||||||
pub core: EmulatorCore<[u8; 4]>,
|
pub core: EmulatorCore<[u8; 4]>,
|
||||||
pub _sender: Sender<EmulatorMessage<[u8; 4]>>,
|
pub sender: Sender<EmulatorMessage<[u8; 4]>>,
|
||||||
pub _audio_rx: async_ringbuf::AsyncHeapCons<[f32; 2]>,
|
pub audio_rx: AsyncHeapConsumer<[f32; 2]>,
|
||||||
pub serial_rx: Receiver<u8>,
|
pub serial_rx: Receiver<u8>,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn emulator_setup(rom_file: RomFile) -> anyhow::Result<TestEmulator> {
|
pub fn emulator_setup(rom_file: RomFile) -> Result<TestEmulator, String> {
|
||||||
let (sender, receiver) = channel::<EmulatorMessage<[u8; 4]>>();
|
let (sender, receiver) = channel::<EmulatorMessage<[u8; 4]>>();
|
||||||
let rom = rom_file.load(gb_emu_lib::connect::SramType::None)?;
|
let rom = rom_file
|
||||||
|
.load(gb_emu_lib::connect::SramType::None)
|
||||||
|
.map_err(|_e| String::from("Error reading ROM: {_e:?}"))?;
|
||||||
let (audio_output, audio_rx) = AudioOutput::new(
|
let (audio_output, audio_rx) = AudioOutput::new(
|
||||||
48000.,
|
48000.,
|
||||||
1,
|
1,
|
||||||
|
@ -37,12 +40,14 @@ pub fn emulator_setup(rom_file: RomFile) -> anyhow::Result<TestEmulator> {
|
||||||
include_bytes!("../../../sameboy-bootroms/dmg_boot.bin").to_vec(),
|
include_bytes!("../../../sameboy-bootroms/dmg_boot.bin").to_vec(),
|
||||||
)));
|
)));
|
||||||
|
|
||||||
let core = EmulatorCore::init(true, receiver, options)?;
|
let core = EmulatorCore::init(true, receiver, options);
|
||||||
sender.send(EmulatorMessage::Start)?;
|
sender
|
||||||
|
.send(EmulatorMessage::Start)
|
||||||
|
.map_err(|_e| String::from("Error sending message: {_e:?}"))?;
|
||||||
Ok(TestEmulator {
|
Ok(TestEmulator {
|
||||||
core,
|
core,
|
||||||
_sender: sender,
|
sender,
|
||||||
_audio_rx: audio_rx,
|
audio_rx,
|
||||||
serial_rx,
|
serial_rx,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue