Compare commits
2 commits
c6d25af1ba
...
ac4446b055
Author | SHA1 | Date | |
---|---|---|---|
Alex Janka | ac4446b055 | ||
Alex Janka | 0c5324176d |
16
Cargo.lock
generated
16
Cargo.lock
generated
|
@ -190,6 +190,9 @@ name = "anyhow"
|
||||||
version = "1.0.86"
|
version = "1.0.86"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "b3d1d046238990b9cf5bcde22a3fb3584ee5cf65fb2765f454ed428c7a0063da"
|
checksum = "b3d1d046238990b9cf5bcde22a3fb3584ee5cf65fb2765f454ed428c7a0063da"
|
||||||
|
dependencies = [
|
||||||
|
"backtrace",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "anymap"
|
name = "anymap"
|
||||||
|
@ -778,6 +781,7 @@ checksum = "98cc8fbded0c607b7ba9dd60cd98df59af97e84d24e49c8557331cfc26d301ce"
|
||||||
name = "cli"
|
name = "cli"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"anyhow",
|
||||||
"clap",
|
"clap",
|
||||||
"ctrlc",
|
"ctrlc",
|
||||||
"env_logger",
|
"env_logger",
|
||||||
|
@ -1583,6 +1587,7 @@ dependencies = [
|
||||||
name = "frontend-common"
|
name = "frontend-common"
|
||||||
version = "0.5.1"
|
version = "0.5.1"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"anyhow",
|
||||||
"bytemuck",
|
"bytemuck",
|
||||||
"chrono",
|
"chrono",
|
||||||
"cpal",
|
"cpal",
|
||||||
|
@ -1702,6 +1707,7 @@ dependencies = [
|
||||||
name = "gb-emu-lib"
|
name = "gb-emu-lib"
|
||||||
version = "0.5.1"
|
version = "0.5.1"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"anyhow",
|
||||||
"ash 0.38.0+1.3.281",
|
"ash 0.38.0+1.3.281",
|
||||||
"ash-molten",
|
"ash-molten",
|
||||||
"ash-window",
|
"ash-window",
|
||||||
|
@ -2207,6 +2213,7 @@ dependencies = [
|
||||||
name = "gui"
|
name = "gui"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"anyhow",
|
||||||
"cacao",
|
"cacao",
|
||||||
"cpal",
|
"cpal",
|
||||||
"env_logger",
|
"env_logger",
|
||||||
|
@ -2637,7 +2644,6 @@ dependencies = [
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "librashader"
|
name = "librashader"
|
||||||
version = "0.2.7"
|
version = "0.2.7"
|
||||||
source = "git+https://git.alexjanka.com/alex/librashader#30bb747e94e7ab11ea5aecf388f4b693ac836434"
|
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"ash 0.37.3+1.3.251",
|
"ash 0.37.3+1.3.251",
|
||||||
"halfbrown",
|
"halfbrown",
|
||||||
|
@ -2656,7 +2662,6 @@ dependencies = [
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "librashader-cache"
|
name = "librashader-cache"
|
||||||
version = "0.2.7"
|
version = "0.2.7"
|
||||||
source = "git+https://git.alexjanka.com/alex/librashader#30bb747e94e7ab11ea5aecf388f4b693ac836434"
|
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bincode",
|
"bincode",
|
||||||
"blake3",
|
"blake3",
|
||||||
|
@ -2672,7 +2677,6 @@ dependencies = [
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "librashader-common"
|
name = "librashader-common"
|
||||||
version = "0.2.7"
|
version = "0.2.7"
|
||||||
source = "git+https://git.alexjanka.com/alex/librashader#30bb747e94e7ab11ea5aecf388f4b693ac836434"
|
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"ash 0.37.3+1.3.251",
|
"ash 0.37.3+1.3.251",
|
||||||
"halfbrown",
|
"halfbrown",
|
||||||
|
@ -2684,7 +2688,6 @@ dependencies = [
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "librashader-preprocess"
|
name = "librashader-preprocess"
|
||||||
version = "0.2.7"
|
version = "0.2.7"
|
||||||
source = "git+https://git.alexjanka.com/alex/librashader#30bb747e94e7ab11ea5aecf388f4b693ac836434"
|
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"encoding_rs",
|
"encoding_rs",
|
||||||
"librashader-common",
|
"librashader-common",
|
||||||
|
@ -2695,7 +2698,6 @@ dependencies = [
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "librashader-presets"
|
name = "librashader-presets"
|
||||||
version = "0.2.7"
|
version = "0.2.7"
|
||||||
source = "git+https://git.alexjanka.com/alex/librashader#30bb747e94e7ab11ea5aecf388f4b693ac836434"
|
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"librashader-common",
|
"librashader-common",
|
||||||
"nom",
|
"nom",
|
||||||
|
@ -2711,7 +2713,6 @@ dependencies = [
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "librashader-reflect"
|
name = "librashader-reflect"
|
||||||
version = "0.2.7"
|
version = "0.2.7"
|
||||||
source = "git+https://git.alexjanka.com/alex/librashader#30bb747e94e7ab11ea5aecf388f4b693ac836434"
|
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bitflags 2.5.0",
|
"bitflags 2.5.0",
|
||||||
"bytemuck",
|
"bytemuck",
|
||||||
|
@ -2733,7 +2734,6 @@ dependencies = [
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "librashader-runtime"
|
name = "librashader-runtime"
|
||||||
version = "0.2.7"
|
version = "0.2.7"
|
||||||
source = "git+https://git.alexjanka.com/alex/librashader#30bb747e94e7ab11ea5aecf388f4b693ac836434"
|
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"array-concat",
|
"array-concat",
|
||||||
"bytemuck",
|
"bytemuck",
|
||||||
|
@ -2749,7 +2749,6 @@ dependencies = [
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "librashader-runtime-vk"
|
name = "librashader-runtime-vk"
|
||||||
version = "0.2.7"
|
version = "0.2.7"
|
||||||
source = "git+https://git.alexjanka.com/alex/librashader#30bb747e94e7ab11ea5aecf388f4b693ac836434"
|
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"array-concat",
|
"array-concat",
|
||||||
"ash 0.37.3+1.3.251",
|
"ash 0.37.3+1.3.251",
|
||||||
|
@ -2769,7 +2768,6 @@ dependencies = [
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "librashader-runtime-wgpu"
|
name = "librashader-runtime-wgpu"
|
||||||
version = "0.2.7"
|
version = "0.2.7"
|
||||||
source = "git+https://git.alexjanka.com/alex/librashader#30bb747e94e7ab11ea5aecf388f4b693ac836434"
|
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"array-concat",
|
"array-concat",
|
||||||
"bytemuck",
|
"bytemuck",
|
||||||
|
|
|
@ -14,3 +14,4 @@ clap = { version = "4.4", features = ["derive"] }
|
||||||
ctrlc = "3.4"
|
ctrlc = "3.4"
|
||||||
log = { workspace = true }
|
log = { workspace = true }
|
||||||
env_logger = { workspace = true }
|
env_logger = { workspace = true }
|
||||||
|
anyhow = { version = "1.0.86", features = ["backtrace"] }
|
||||||
|
|
|
@ -121,7 +121,7 @@ impl From<Args> for frontend_common::RunOptions {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() {
|
fn main() -> anyhow::Result<()> {
|
||||||
env_logger::init();
|
env_logger::init();
|
||||||
let args = Args::parse();
|
let args = Args::parse();
|
||||||
|
|
||||||
|
@ -170,7 +170,7 @@ fn main() {
|
||||||
let prepared = frontend_common::prepare(args.into(), receiver);
|
let prepared = frontend_common::prepare(args.into(), receiver);
|
||||||
let (output, stream) = audio::create_output(mute);
|
let (output, stream) = audio::create_output(mute);
|
||||||
let mut window_manager = ActiveWindowManager::new(sender, stream, record);
|
let mut window_manager = ActiveWindowManager::new(sender, stream, record);
|
||||||
let mut core = frontend_common::run(prepared, &mut window_manager, output);
|
let mut core = frontend_common::run(prepared, &mut window_manager, output)?;
|
||||||
if debug {
|
if debug {
|
||||||
let mut debugger = Debugger::new(Box::new(core));
|
let mut debugger = Debugger::new(Box::new(core));
|
||||||
let mut since = Instant::now();
|
let mut since = Instant::now();
|
||||||
|
@ -190,6 +190,7 @@ fn main() {
|
||||||
window_manager.run_events_blocking().unwrap();
|
window_manager.run_events_blocking().unwrap();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
const UPDATE_INTERVAL: Duration = Duration::from_millis(1);
|
const UPDATE_INTERVAL: Duration = Duration::from_millis(1);
|
||||||
|
|
|
@ -29,3 +29,4 @@ 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 }
|
||||||
|
anyhow = "1.0.86"
|
||||||
|
|
|
@ -167,7 +167,7 @@ pub fn run<W>(
|
||||||
prepared: PreparedEmulator,
|
prepared: PreparedEmulator,
|
||||||
window_manager: &mut W,
|
window_manager: &mut W,
|
||||||
output: AudioOutput,
|
output: AudioOutput,
|
||||||
) -> EmulatorCore<[u8; 4]>
|
) -> anyhow::Result<EmulatorCore<[u8; 4]>>
|
||||||
where
|
where
|
||||||
W: WindowManager,
|
W: WindowManager,
|
||||||
{
|
{
|
||||||
|
@ -178,16 +178,16 @@ where
|
||||||
prepared.scale_override,
|
prepared.scale_override,
|
||||||
prepared.shader_path,
|
prepared.shader_path,
|
||||||
prepared.resizable,
|
prepared.resizable,
|
||||||
);
|
)?;
|
||||||
|
|
||||||
let tile_window = if prepared.tile_window {
|
let tile_window = if prepared.tile_window {
|
||||||
Some(new_tile_window(window_manager))
|
Some(new_tile_window(window_manager)?)
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
};
|
};
|
||||||
|
|
||||||
let layer_window = if prepared.layer_window {
|
let layer_window = if prepared.layer_window {
|
||||||
Some(new_layer_window(window_manager))
|
Some(new_layer_window(window_manager)?)
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
};
|
};
|
||||||
|
@ -224,7 +224,7 @@ where
|
||||||
EmulatorCore::init(true, prepared.receiver, emulator_options)
|
EmulatorCore::init(true, prepared.receiver, emulator_options)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn new_tile_window<W>(window_manager: &mut W) -> RendererChannel
|
pub fn new_tile_window<W>(window_manager: &mut W) -> anyhow::Result<RendererChannel>
|
||||||
where
|
where
|
||||||
W: WindowManager,
|
W: WindowManager,
|
||||||
{
|
{
|
||||||
|
@ -236,7 +236,7 @@ where
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn new_layer_window<W>(window_manager: &mut W) -> RendererChannel
|
pub fn new_layer_window<W>(window_manager: &mut W) -> anyhow::Result<RendererChannel>
|
||||||
where
|
where
|
||||||
W: WindowManager,
|
W: WindowManager,
|
||||||
{
|
{
|
||||||
|
|
|
@ -21,5 +21,5 @@ pub trait WindowManager {
|
||||||
factor: usize,
|
factor: usize,
|
||||||
shader_path: Option<PathBuf>,
|
shader_path: Option<PathBuf>,
|
||||||
resizable: bool,
|
resizable: bool,
|
||||||
) -> RendererChannel;
|
) -> anyhow::Result<RendererChannel>;
|
||||||
}
|
}
|
||||||
|
|
|
@ -56,6 +56,7 @@ where
|
||||||
impl<Backend> WinitWindowManager<Backend>
|
impl<Backend> WinitWindowManager<Backend>
|
||||||
where
|
where
|
||||||
Backend: RendererBackend,
|
Backend: RendererBackend,
|
||||||
|
<Backend as RendererBackend>::RendererError: Sync + Send + 'static,
|
||||||
{
|
{
|
||||||
pub fn new(
|
pub fn new(
|
||||||
sender: Sender<EmulatorMessage<[u8; 4]>>,
|
sender: Sender<EmulatorMessage<[u8; 4]>>,
|
||||||
|
@ -97,6 +98,7 @@ where
|
||||||
impl<Backend> WindowManager for WinitWindowManager<Backend>
|
impl<Backend> WindowManager for WinitWindowManager<Backend>
|
||||||
where
|
where
|
||||||
Backend: RendererBackend,
|
Backend: RendererBackend,
|
||||||
|
<Backend as RendererBackend>::RendererError: Sync + Send + 'static,
|
||||||
{
|
{
|
||||||
fn add(
|
fn add(
|
||||||
&mut self,
|
&mut self,
|
||||||
|
@ -104,7 +106,7 @@ where
|
||||||
factor: usize,
|
factor: usize,
|
||||||
shader_path: Option<PathBuf>,
|
shader_path: Option<PathBuf>,
|
||||||
resizable: bool,
|
resizable: bool,
|
||||||
) -> RendererChannel {
|
) -> anyhow::Result<RendererChannel> {
|
||||||
let is_main = window_type == WindowType::Main;
|
let is_main = window_type == WindowType::Main;
|
||||||
|
|
||||||
self.data.add(
|
self.data.add(
|
||||||
|
@ -121,6 +123,7 @@ where
|
||||||
impl<Backend> WinitWindowManagerData<Backend>
|
impl<Backend> WinitWindowManagerData<Backend>
|
||||||
where
|
where
|
||||||
Backend: RendererBackend,
|
Backend: RendererBackend,
|
||||||
|
<Backend as RendererBackend>::RendererError: Sync + Send + 'static,
|
||||||
{
|
{
|
||||||
fn add(
|
fn add(
|
||||||
&mut self,
|
&mut self,
|
||||||
|
@ -130,7 +133,7 @@ where
|
||||||
event_loop: &EventLoop<()>,
|
event_loop: &EventLoop<()>,
|
||||||
is_main: bool,
|
is_main: bool,
|
||||||
record: bool,
|
record: bool,
|
||||||
) -> RendererChannel {
|
) -> anyhow::Result<RendererChannel> {
|
||||||
let (r, sender) = WindowRenderer::new(
|
let (r, sender) = WindowRenderer::new(
|
||||||
factor,
|
factor,
|
||||||
event_loop,
|
event_loop,
|
||||||
|
@ -138,13 +141,13 @@ where
|
||||||
shader_path,
|
shader_path,
|
||||||
resizable,
|
resizable,
|
||||||
record,
|
record,
|
||||||
);
|
)?;
|
||||||
let id = r.window.id();
|
let id = r.window.id();
|
||||||
self.windows.insert(id, r);
|
self.windows.insert(id, r);
|
||||||
if is_main {
|
if is_main {
|
||||||
self.main_window = Some(id);
|
self.main_window = Some(id);
|
||||||
}
|
}
|
||||||
sender
|
Ok(sender)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn handler(&mut self, run_return: bool, event: Event<()>, target: &EventLoopWindowTarget<()>) {
|
fn handler(&mut self, run_return: bool, event: Event<()>, target: &EventLoopWindowTarget<()>) {
|
||||||
|
@ -320,6 +323,7 @@ impl QueuedBuf {
|
||||||
impl<Backend> WindowRenderer<Backend>
|
impl<Backend> WindowRenderer<Backend>
|
||||||
where
|
where
|
||||||
Backend: RendererBackend,
|
Backend: RendererBackend,
|
||||||
|
<Backend as RendererBackend>::RendererError: Sync + Send + 'static,
|
||||||
{
|
{
|
||||||
#[allow(unused_variables)]
|
#[allow(unused_variables)]
|
||||||
fn new(
|
fn new(
|
||||||
|
@ -329,12 +333,11 @@ where
|
||||||
shader_path: Option<PathBuf>,
|
shader_path: Option<PathBuf>,
|
||||||
resizable: bool,
|
resizable: bool,
|
||||||
record: bool,
|
record: bool,
|
||||||
) -> (Self, RendererChannel) {
|
) -> anyhow::Result<(Self, RendererChannel)> {
|
||||||
let window = WindowBuilder::new()
|
let window = WindowBuilder::new()
|
||||||
.with_title("Gameboy")
|
.with_title("Gameboy")
|
||||||
.with_resizable(resizable)
|
.with_resizable(resizable)
|
||||||
.build(event_loop)
|
.build(event_loop)?;
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
let real_factor = (window.scale_factor() * factor as f64) as u32;
|
let real_factor = (window.scale_factor() * factor as f64) as u32;
|
||||||
let inner_size = window.inner_size();
|
let inner_size = window.inner_size();
|
||||||
|
@ -344,8 +347,9 @@ where
|
||||||
scaled_width: inner_size.width / real_factor,
|
scaled_width: inner_size.width / real_factor,
|
||||||
scaled_height: inner_size.height / real_factor,
|
scaled_height: inner_size.height / real_factor,
|
||||||
};
|
};
|
||||||
|
let renderer = RendererBackend::new(resolutions, &window, shader_path, manager);
|
||||||
|
|
||||||
let renderer = RendererBackend::new(resolutions, &window, shader_path, manager).unwrap();
|
let renderer = renderer?;
|
||||||
|
|
||||||
let recording = if record {
|
let recording = if record {
|
||||||
let configs = access_config();
|
let configs = access_config();
|
||||||
|
@ -365,7 +369,7 @@ where
|
||||||
|
|
||||||
let (sender, receiver) = mpsc::channel();
|
let (sender, receiver) = mpsc::channel();
|
||||||
|
|
||||||
(
|
Ok((
|
||||||
Self {
|
Self {
|
||||||
receiver,
|
receiver,
|
||||||
renderer,
|
renderer,
|
||||||
|
@ -377,7 +381,7 @@ where
|
||||||
recording,
|
recording,
|
||||||
},
|
},
|
||||||
sender,
|
sender,
|
||||||
)
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn render(&mut self, manager: &Backend::RendererBackendManager) {
|
fn render(&mut self, manager: &Backend::RendererBackendManager) {
|
||||||
|
|
|
@ -31,6 +31,7 @@ log = { workspace = true }
|
||||||
env_logger = { workspace = true }
|
env_logger = { workspace = true }
|
||||||
thiserror = { workspace = true }
|
thiserror = { workspace = true }
|
||||||
serde = { version = "1.0", features = ["derive"] }
|
serde = { version = "1.0", features = ["derive"] }
|
||||||
|
anyhow = "1.0.86"
|
||||||
|
|
||||||
[target.'cfg(any(target_os = "macos"))'.dependencies]
|
[target.'cfg(any(target_os = "macos"))'.dependencies]
|
||||||
cacao = { git = "https://git.alexjanka.com/alex/cacao", optional = true }
|
cacao = { git = "https://git.alexjanka.com/alex/cacao", optional = true }
|
||||||
|
|
|
@ -335,7 +335,7 @@ impl WindowManager for CacaoWindowManager {
|
||||||
factor: usize,
|
factor: usize,
|
||||||
shader_path: Option<std::path::PathBuf>,
|
shader_path: Option<std::path::PathBuf>,
|
||||||
resizable: bool,
|
resizable: bool,
|
||||||
) -> RendererChannel {
|
) -> anyhow::Result<RendererChannel> {
|
||||||
let (w, receiver) = CacaoWindow::new(
|
let (w, receiver) = CacaoWindow::new(
|
||||||
window_type,
|
window_type,
|
||||||
factor,
|
factor,
|
||||||
|
@ -364,7 +364,7 @@ impl WindowManager for CacaoWindowManager {
|
||||||
window.show();
|
window.show();
|
||||||
self.windows
|
self.windows
|
||||||
.insert(window.delegate.as_ref().unwrap().window_type, window);
|
.insert(window.delegate.as_ref().unwrap().window_type, window);
|
||||||
receiver
|
Ok(receiver)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -54,6 +54,7 @@ lazy_static = "1.4"
|
||||||
wgpu = { version = "0.20", optional = true }
|
wgpu = { version = "0.20", optional = true }
|
||||||
thiserror = { workspace = true }
|
thiserror = { workspace = true }
|
||||||
log = { workspace = true }
|
log = { workspace = true }
|
||||||
|
anyhow = "1.0.86"
|
||||||
|
|
||||||
[build-dependencies]
|
[build-dependencies]
|
||||||
naga = { version = "0.19", optional = true, features = ["wgsl-in", "spv-out"] }
|
naga = { version = "0.19", optional = true, features = ["wgsl-in", "spv-out"] }
|
||||||
|
|
|
@ -3,12 +3,13 @@ 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 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};
|
||||||
pub use crate::processor::memory::mmio::serial::{SerialTarget, StdoutType};
|
pub use crate::processor::memory::mmio::serial::{SerialTarget, StdoutType};
|
||||||
use crate::processor::memory::rom::sram_save::SaveDataLocation;
|
use crate::processor::memory::rom::sram_save::SaveDataLocation;
|
||||||
pub use crate::processor::memory::rom::{
|
pub use crate::processor::memory::rom::{
|
||||||
licensee::LicenseeCode, CartridgeType, CgbRomType, RamSize, RomHeader, RomHeaderError, RomSize,
|
licensee::LicenseeCode, CartridgeType, CgbRomType, RamSize, RomHeader, RomSize,
|
||||||
};
|
};
|
||||||
pub use crate::processor::memory::Rom;
|
pub use crate::processor::memory::Rom;
|
||||||
pub use crate::{HEIGHT, WIDTH};
|
pub use crate::{HEIGHT, WIDTH};
|
||||||
|
|
55
lib/src/error.rs
Normal file
55
lib/src/error.rs
Normal file
|
@ -0,0 +1,55 @@
|
||||||
|
use thiserror::Error;
|
||||||
|
|
||||||
|
#[derive(Debug, Error)]
|
||||||
|
pub enum RomHeaderError {
|
||||||
|
#[error("slice not long enough for rom file")]
|
||||||
|
SliceLength,
|
||||||
|
#[error(transparent)]
|
||||||
|
Utf8(#[from] std::str::Utf8Error),
|
||||||
|
#[error("invalid ROM size")]
|
||||||
|
InvalidRomSize,
|
||||||
|
#[error("invalid RAM size")]
|
||||||
|
InvalidRamSize,
|
||||||
|
#[error("invalid MBC")]
|
||||||
|
InvalidMBC,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub(crate) enum AddressError {
|
||||||
|
OutOfBounds,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "pixels-renderer")]
|
||||||
|
#[derive(Debug, Error)]
|
||||||
|
pub enum PixelsError {
|
||||||
|
#[error("pixels error")]
|
||||||
|
Pixels(#[from] pixels::Error),
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "wgpu-renderer")]
|
||||||
|
#[derive(Debug, Error)]
|
||||||
|
pub enum WgpuError {
|
||||||
|
#[error("no adapter")]
|
||||||
|
NoAdapter,
|
||||||
|
#[error("no texture format")]
|
||||||
|
NoTextureFormat,
|
||||||
|
#[error("rwh error")]
|
||||||
|
RawWindowHandle(#[from] raw_window_handle::HandleError),
|
||||||
|
#[error("create surface error")]
|
||||||
|
CreateSurface(#[from] wgpu::CreateSurfaceError),
|
||||||
|
#[error("wgpu surface error")]
|
||||||
|
Surface(#[from] wgpu::SurfaceError),
|
||||||
|
#[error("request device error")]
|
||||||
|
RequestDevice(#[from] wgpu::RequestDeviceError),
|
||||||
|
#[error("librashader filterchain error")]
|
||||||
|
FilterChain(#[from] librashader::runtime::wgpu::error::FilterChainError),
|
||||||
|
#[error("couldn't load")]
|
||||||
|
CouldntLoad,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "vulkan-renderer")]
|
||||||
|
#[derive(Debug, Error)]
|
||||||
|
pub enum VulkanError {
|
||||||
|
#[error("vulkan error")]
|
||||||
|
Vulkan, //(#[from] vk::Error),
|
||||||
|
}
|
|
@ -1,6 +1,7 @@
|
||||||
#![feature(let_chains, bigint_helper_methods)]
|
#![feature(let_chains, bigint_helper_methods)]
|
||||||
|
|
||||||
use crate::processor::{memory::Memory, Flags};
|
use crate::processor::{memory::Memory, Flags};
|
||||||
|
use anyhow::Context;
|
||||||
use connect::{AudioOutput, EmulatorCoreTrait, EmulatorMessage, EmulatorOptions, RomFile};
|
use connect::{AudioOutput, EmulatorCoreTrait, EmulatorMessage, EmulatorOptions, RomFile};
|
||||||
use processor::{
|
use processor::{
|
||||||
memory::{mmio::gpu::Colour, rom::CgbRomType, OutputTargets},
|
memory::{mmio::gpu::Colour, rom::CgbRomType, OutputTargets},
|
||||||
|
@ -8,6 +9,7 @@ use processor::{
|
||||||
};
|
};
|
||||||
use std::sync::mpsc::Receiver;
|
use std::sync::mpsc::Receiver;
|
||||||
|
|
||||||
|
pub mod error;
|
||||||
pub mod renderer;
|
pub mod renderer;
|
||||||
|
|
||||||
#[cfg(feature = "config")]
|
#[cfg(feature = "config")]
|
||||||
|
@ -31,13 +33,13 @@ where
|
||||||
|
|
||||||
impl<ColourFormat> EmulatorCore<ColourFormat>
|
impl<ColourFormat> EmulatorCore<ColourFormat>
|
||||||
where
|
where
|
||||||
ColourFormat: From<Colour> + Copy,
|
ColourFormat: From<Colour> + Copy + Sync + Send + 'static,
|
||||||
{
|
{
|
||||||
pub fn init(
|
pub fn init(
|
||||||
paused: bool,
|
paused: bool,
|
||||||
receiver: Receiver<EmulatorMessage<ColourFormat>>,
|
receiver: Receiver<EmulatorMessage<ColourFormat>>,
|
||||||
options: EmulatorOptions<ColourFormat>,
|
options: EmulatorOptions<ColourFormat>,
|
||||||
) -> Self {
|
) -> anyhow::Result<Self> {
|
||||||
let rom = options.rom;
|
let rom = options.rom;
|
||||||
|
|
||||||
let is_cgb_mode = rom.rom_type == CgbRomType::CgbOnly || options.cgb_mode;
|
let is_cgb_mode = rom.rom_type == CgbRomType::CgbOnly || options.cgb_mode;
|
||||||
|
@ -51,28 +53,24 @@ where
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
.load_data()
|
.load_data()
|
||||||
.expect("Error loading bootrom!");
|
.context("couldn't load bootrom")?;
|
||||||
|
|
||||||
if let Some(window) = &options.window {
|
if let Some(window) = &options.window {
|
||||||
window
|
window.send(connect::RendererMessage::Prepare {
|
||||||
.send(connect::RendererMessage::Prepare {
|
|
||||||
width: WIDTH,
|
width: WIDTH,
|
||||||
height: HEIGHT,
|
height: HEIGHT,
|
||||||
})
|
})?;
|
||||||
.expect("message error");
|
window.send(connect::RendererMessage::SetTitle {
|
||||||
window
|
|
||||||
.send(connect::RendererMessage::SetTitle {
|
|
||||||
title: format!(
|
title: format!(
|
||||||
"{} on {} on {}",
|
"{} on {} on {}",
|
||||||
rom.get_title(),
|
rom.get_title(),
|
||||||
rom.mbc_type(),
|
rom.mbc_type(),
|
||||||
if is_cgb_mode { "CGB" } else { "DMG" }
|
if is_cgb_mode { "CGB" } else { "DMG" }
|
||||||
),
|
),
|
||||||
})
|
})?
|
||||||
.expect("message error");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Self::new(
|
Ok(Self::new(
|
||||||
paused,
|
paused,
|
||||||
receiver,
|
receiver,
|
||||||
Cpu::new(
|
Cpu::new(
|
||||||
|
@ -91,9 +89,14 @@ where
|
||||||
options.show_bootrom,
|
options.show_bootrom,
|
||||||
options.no_output,
|
options.no_output,
|
||||||
),
|
),
|
||||||
)
|
))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<ColourFormat> EmulatorCore<ColourFormat>
|
||||||
|
where
|
||||||
|
ColourFormat: From<Colour> + Copy,
|
||||||
|
{
|
||||||
fn new(
|
fn new(
|
||||||
paused: bool,
|
paused: bool,
|
||||||
receiver: Receiver<EmulatorMessage<ColourFormat>>,
|
receiver: Receiver<EmulatorMessage<ColourFormat>>,
|
||||||
|
|
|
@ -3,6 +3,8 @@ use std::{
|
||||||
ops::{Add, Sub},
|
ops::{Add, Sub},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
use crate::error::AddressError;
|
||||||
|
|
||||||
pub(crate) use self::types::*;
|
pub(crate) use self::types::*;
|
||||||
|
|
||||||
mod types;
|
mod types;
|
||||||
|
|
|
@ -3,10 +3,7 @@ use std::{
|
||||||
ops::{Add, Sub},
|
ops::{Add, Sub},
|
||||||
};
|
};
|
||||||
|
|
||||||
#[derive(Debug)]
|
use crate::error::AddressError;
|
||||||
pub(crate) enum AddressError {
|
|
||||||
OutOfBounds,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Copy, Clone, Debug)]
|
#[derive(Copy, Clone, Debug)]
|
||||||
pub(crate) struct BoundedAddress<const MIN: u16, const MAX: u16>(u16);
|
pub(crate) struct BoundedAddress<const MIN: u16, const MAX: u16>(u16);
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
use crate::error::RomHeaderError;
|
||||||
|
|
||||||
use self::{
|
use self::{
|
||||||
licensee::LicenseeCode,
|
licensee::LicenseeCode,
|
||||||
mbcs::{Mbc, Mbc1, Mbc2, Mbc3, Mbc5, None, KB, ROM_BANK_SIZE},
|
mbcs::{Mbc, Mbc1, Mbc2, Mbc3, Mbc5, None, KB, ROM_BANK_SIZE},
|
||||||
|
@ -5,7 +7,6 @@ use self::{
|
||||||
};
|
};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use std::str::from_utf8;
|
use std::str::from_utf8;
|
||||||
use thiserror::Error;
|
|
||||||
|
|
||||||
use super::addresses::{CartRamAddress, RomAddress};
|
use super::addresses::{CartRamAddress, RomAddress};
|
||||||
|
|
||||||
|
@ -323,20 +324,6 @@ impl RomHeader {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Error)]
|
|
||||||
pub enum RomHeaderError {
|
|
||||||
#[error("slice not long enough for rom file")]
|
|
||||||
SliceLength,
|
|
||||||
#[error("parsing UTF-8")]
|
|
||||||
Utf8(#[from] std::str::Utf8Error),
|
|
||||||
#[error("invalid ROM size")]
|
|
||||||
InvalidRomSize,
|
|
||||||
#[error("invalid RAM size")]
|
|
||||||
InvalidRamSize,
|
|
||||||
#[error("invalid MBC")]
|
|
||||||
InvalidMBC,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Rom {
|
impl Rom {
|
||||||
pub(crate) fn load(data: Vec<u8>, sram_location: Option<SaveDataLocation>) -> Self {
|
pub(crate) fn load(data: Vec<u8>, sram_location: Option<SaveDataLocation>) -> Self {
|
||||||
let header_data = RomHeader::parse(&data).unwrap();
|
let header_data = RomHeader::parse(&data).unwrap();
|
||||||
|
|
|
@ -2,9 +2,8 @@ use std::{path::PathBuf, sync::Arc};
|
||||||
|
|
||||||
use pixels::{Pixels, SurfaceTexture};
|
use pixels::{Pixels, SurfaceTexture};
|
||||||
use raw_window_handle::{DisplayHandle, HasDisplayHandle, HasWindowHandle};
|
use raw_window_handle::{DisplayHandle, HasDisplayHandle, HasWindowHandle};
|
||||||
use thiserror::Error;
|
|
||||||
|
|
||||||
use crate::connect::ResolutionData;
|
use crate::{connect::ResolutionData, error::PixelsError};
|
||||||
|
|
||||||
use super::{RendererBackend, RendererBackendManager};
|
use super::{RendererBackend, RendererBackendManager};
|
||||||
|
|
||||||
|
@ -82,12 +81,6 @@ fn new_pixels<W: HasDisplayHandle + HasWindowHandle>(
|
||||||
.build()
|
.build()
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Error)]
|
|
||||||
pub enum PixelsError {
|
|
||||||
#[error("pixels error")]
|
|
||||||
Pixels(#[from] pixels::Error),
|
|
||||||
}
|
|
||||||
|
|
||||||
struct DummyHandle<'a> {
|
struct DummyHandle<'a> {
|
||||||
window: raw_window_handle::WindowHandle<'a>,
|
window: raw_window_handle::WindowHandle<'a>,
|
||||||
display: raw_window_handle::DisplayHandle<'a>,
|
display: raw_window_handle::DisplayHandle<'a>,
|
||||||
|
|
|
@ -13,12 +13,6 @@ use super::{
|
||||||
VulkanBackendManager,
|
VulkanBackendManager,
|
||||||
};
|
};
|
||||||
|
|
||||||
#[derive(Debug, Error)]
|
|
||||||
pub enum VulkanError {
|
|
||||||
#[error("vulkan error")]
|
|
||||||
Vulkan, //(#[from] vk::Error),
|
|
||||||
}
|
|
||||||
|
|
||||||
pub(super) const SHADER_INPUT_FORMAT: vk::Format = vk::Format::R8G8B8A8_UNORM;
|
pub(super) const SHADER_INPUT_FORMAT: vk::Format = vk::Format::R8G8B8A8_UNORM;
|
||||||
|
|
||||||
#[derive(Clone, Debug, Copy)]
|
#[derive(Clone, Debug, Copy)]
|
||||||
|
|
|
@ -3,11 +3,11 @@ use std::sync::Arc;
|
||||||
use futures::executor::block_on;
|
use futures::executor::block_on;
|
||||||
use librashader::runtime::wgpu::{FilterChain, FilterChainOptions};
|
use librashader::runtime::wgpu::{FilterChain, FilterChainOptions};
|
||||||
use raw_window_handle::{DisplayHandle, HasDisplayHandle, HasWindowHandle};
|
use raw_window_handle::{DisplayHandle, HasDisplayHandle, HasWindowHandle};
|
||||||
use thiserror::Error;
|
|
||||||
use wgpu::{Device, Queue, Surface, SurfaceConfiguration};
|
use wgpu::{Device, Queue, Surface, SurfaceConfiguration};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
connect::ResolutionData,
|
connect::ResolutionData,
|
||||||
|
error::WgpuError,
|
||||||
renderer::{RendererBackend, RendererBackendManager},
|
renderer::{RendererBackend, RendererBackendManager},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -125,23 +125,23 @@ impl RendererBackend for WgpuBackend {
|
||||||
let filter_chain_options = FilterChainOptions {
|
let filter_chain_options = FilterChainOptions {
|
||||||
force_no_mipmaps: false,
|
force_no_mipmaps: false,
|
||||||
};
|
};
|
||||||
match shader_path {
|
shader_path
|
||||||
Some(path) => FilterChain::load_from_path(
|
.and_then(|path| {
|
||||||
|
FilterChain::load_from_path(
|
||||||
path,
|
path,
|
||||||
device.clone(),
|
device.clone(),
|
||||||
queue.clone(),
|
queue.clone(),
|
||||||
Some(&filter_chain_options),
|
Some(&filter_chain_options),
|
||||||
)
|
)
|
||||||
.unwrap(), //?,
|
.inspect_err(|e| log::error!("couldn't load shader: {e:?}"))
|
||||||
None => {
|
.ok()
|
||||||
FilterChain::load_from_preset(
|
})
|
||||||
|
.unwrap_or(FilterChain::load_from_preset(
|
||||||
default_preset(),
|
default_preset(),
|
||||||
device.clone(),
|
device.clone(),
|
||||||
queue.clone(),
|
queue.clone(),
|
||||||
Some(&filter_chain_options),
|
Some(&filter_chain_options),
|
||||||
)
|
)?)
|
||||||
}?,
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
let gb_framebuffer = Arc::new(device.create_texture(&wgpu::TextureDescriptor {
|
let gb_framebuffer = Arc::new(device.create_texture(&wgpu::TextureDescriptor {
|
||||||
|
@ -268,21 +268,3 @@ impl RendererBackend for WgpuBackend {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Error)]
|
|
||||||
pub enum WgpuError {
|
|
||||||
#[error("no adapter")]
|
|
||||||
NoAdapter,
|
|
||||||
#[error("no texture format")]
|
|
||||||
NoTextureFormat,
|
|
||||||
#[error("rwh error")]
|
|
||||||
RawWindowHandle(#[from] raw_window_handle::HandleError),
|
|
||||||
#[error("create surface error")]
|
|
||||||
CreateSurface(#[from] wgpu::CreateSurfaceError),
|
|
||||||
#[error("wgpu surface error")]
|
|
||||||
Surface(#[from] wgpu::SurfaceError),
|
|
||||||
#[error("request device error")]
|
|
||||||
RequestDevice(#[from] wgpu::RequestDeviceError),
|
|
||||||
#[error("librashader filterchain error")]
|
|
||||||
FilterChain(#[from] librashader::runtime::wgpu::error::FilterChainError),
|
|
||||||
}
|
|
||||||
|
|
Loading…
Reference in a new issue