chore: work towards backend rewrite
egui now has egui-winit and egui-wgpu, which I can use instead of the community-run libraries. Unfortunately, despite being based on community work, not all the necessary features made it over, as of 5 days ago (according to the commit date) the necessary APIs were implemented, but until egui-winit and egui-wgpu are updated there's not much I can do
This commit is contained in:
parent
88404dbf35
commit
fc6516cbb2
File diff suppressed because it is too large
Load Diff
|
@ -11,11 +11,8 @@ anyhow = "1.0"
|
|||
bitfield = "0.13"
|
||||
clap = { version = "3.1", features = ["cargo"] }
|
||||
gilrs = "0.9"
|
||||
winit = "0.26"
|
||||
egui = "0.15"
|
||||
wgpu = "0.11"
|
||||
egui_wgpu_backend = "0.14"
|
||||
egui_winit_platform = "0.12"
|
||||
egui-wgpu = "0.18"
|
||||
egui-winit = "0.18"
|
||||
pollster = "0.2"
|
||||
rodio = "0.15"
|
||||
rtrb = "0.2"
|
||||
|
@ -23,7 +20,7 @@ directories-next = "2.0"
|
|||
tracing = "0.1"
|
||||
tracing-subscriber = { version = "0.3", features = ["std", "env-filter"] }
|
||||
thiserror = "1.0"
|
||||
once_cell = "1.10"
|
||||
once_cell = "1.12"
|
||||
|
||||
[profile.release]
|
||||
debug = true
|
||||
|
|
|
@ -4,14 +4,14 @@ use crate::cartridge::Cartridge;
|
|||
use crate::cpu::Cpu;
|
||||
use crate::{Cycle, GB_HEIGHT, GB_WIDTH};
|
||||
use clap::crate_name;
|
||||
use egui_winit::winit::event::KeyboardInput;
|
||||
use egui_winit::winit::event_loop::ControlFlow;
|
||||
use gilrs::Gilrs;
|
||||
use std::fs::File;
|
||||
use std::io::{Read, Write};
|
||||
use std::path::{Path, PathBuf};
|
||||
use std::time::Duration;
|
||||
use thiserror::Error;
|
||||
use winit::event::KeyboardInput;
|
||||
use winit::event_loop::ControlFlow;
|
||||
|
||||
pub const SM83_CYCLE_TIME: Duration = Duration::from_nanos(1_000_000_000 / SM83_CLOCK_SPEED);
|
||||
pub const CYCLES_IN_FRAME: Cycle = 456 * 154; // 456 Cycles times 154 scanlines
|
||||
|
|
64
src/gui.rs
64
src/gui.rs
|
@ -1,6 +1,9 @@
|
|||
use egui::{ClippedMesh, CtxRef, TextureId};
|
||||
use egui_wgpu_backend::{BackendError, RenderPass, ScreenDescriptor};
|
||||
use egui_winit_platform::Platform;
|
||||
use egui_wgpu::wgpu;
|
||||
use egui_winit::egui;
|
||||
use egui_winit::winit;
|
||||
|
||||
use egui::{ClippedPrimitive, Context, TextureId};
|
||||
use egui_wgpu::renderer::{RenderPass, ScreenDescriptor};
|
||||
use wgpu::{
|
||||
Adapter, CommandEncoder, Device, Extent3d, FilterMode, Instance, Queue, RequestDeviceError,
|
||||
Surface, SurfaceConfiguration, SurfaceTexture, Texture, TextureFormat, TextureUsages,
|
||||
|
@ -121,20 +124,6 @@ pub fn surface_config(window: &Window, format: TextureFormat) -> SurfaceConfigur
|
|||
}
|
||||
}
|
||||
|
||||
pub fn platform_desc(window: &Window) -> Platform {
|
||||
use egui::FontDefinitions;
|
||||
use egui_winit_platform::PlatformDescriptor;
|
||||
|
||||
let size = window.inner_size();
|
||||
Platform::new(PlatformDescriptor {
|
||||
physical_width: size.width as u32,
|
||||
physical_height: size.height as u32,
|
||||
scale_factor: window.scale_factor(),
|
||||
font_definitions: FontDefinitions::default(),
|
||||
..Default::default()
|
||||
})
|
||||
}
|
||||
|
||||
pub fn texture_size() -> Extent3d {
|
||||
Extent3d {
|
||||
width: GB_WIDTH as u32,
|
||||
|
@ -184,14 +173,6 @@ pub fn write_to_texture(
|
|||
);
|
||||
}
|
||||
|
||||
pub fn expose_texture_to_egui(
|
||||
render_pass: &mut RenderPass,
|
||||
device: &Device,
|
||||
texture: &Texture,
|
||||
) -> TextureId {
|
||||
render_pass.egui_texture_from_wgpu_texture(device, texture, FILTER_MODE)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn create_view(frame: &SurfaceTexture) -> TextureView {
|
||||
use wgpu::TextureViewDescriptor;
|
||||
|
@ -208,31 +189,19 @@ pub fn create_command_encoder(device: &Device) -> CommandEncoder {
|
|||
})
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn create_screen_descriptor(
|
||||
window: &Window,
|
||||
config: &SurfaceConfiguration,
|
||||
) -> ScreenDescriptor {
|
||||
ScreenDescriptor {
|
||||
physical_width: config.width,
|
||||
physical_height: config.height,
|
||||
scale_factor: window.scale_factor() as f32,
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
car#[inline]
|
||||
pub fn execute_render_pass(
|
||||
render_pass: &mut RenderPass,
|
||||
encoder: &mut CommandEncoder,
|
||||
view: &TextureView,
|
||||
jobs: Vec<ClippedMesh>,
|
||||
jobs: Vec<ClippedPrimitive>,
|
||||
descriptor: &ScreenDescriptor,
|
||||
) -> Result<(), BackendError> {
|
||||
) {
|
||||
render_pass.execute(encoder, view, &jobs, descriptor, Some(wgpu::Color::BLACK))
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn draw_egui(cpu: &Cpu, app: &mut GuiState, ctx: &CtxRef, texture_id: TextureId) {
|
||||
pub fn draw_egui(cpu: &Cpu, app: &mut GuiState, ctx: &Context, texture_id: TextureId) {
|
||||
use crate::{cpu, instruction, ppu};
|
||||
|
||||
fn selectable_text(ui: &mut egui::Ui, mut text: &str) -> egui::Response {
|
||||
|
@ -240,7 +209,7 @@ pub fn draw_egui(cpu: &Cpu, app: &mut GuiState, ctx: &CtxRef, texture_id: Textur
|
|||
}
|
||||
|
||||
egui::TopBottomPanel::top("top_panel").show(ctx, |ui| {
|
||||
egui::menu::menu(ui, "File", |ui| {
|
||||
ui.menu_button("File", |ui| {
|
||||
if ui.button("Quit").clicked() {
|
||||
app.quit = true;
|
||||
}
|
||||
|
@ -322,9 +291,12 @@ pub fn draw_egui(cpu: &Cpu, app: &mut GuiState, ctx: &CtxRef, texture_id: Textur
|
|||
ui.horizontal(|ui| {
|
||||
let ie = cpu.int_enable();
|
||||
|
||||
let r_len = ctx.fonts().glyph_width(egui::TextStyle::Body, 'R');
|
||||
let e_len = ctx.fonts().glyph_width(egui::TextStyle::Body, 'E');
|
||||
let q_len = ctx.fonts().glyph_width(egui::TextStyle::Body, 'Q');
|
||||
let style = ctx.style();
|
||||
let font_id = egui::TextStyle::Body.resolve(&style);
|
||||
|
||||
let r_len = ctx.fonts().glyph_width(&font_id, 'R');
|
||||
let e_len = ctx.fonts().glyph_width(&font_id, 'E');
|
||||
let q_len = ctx.fonts().glyph_width(&font_id, 'Q');
|
||||
|
||||
ui.label("IE:");
|
||||
ui.add_space(q_len - (e_len - r_len));
|
||||
|
@ -350,7 +322,7 @@ pub fn draw_egui(cpu: &Cpu, app: &mut GuiState, ctx: &CtxRef, texture_id: Textur
|
|||
}
|
||||
|
||||
pub mod kbd {
|
||||
use winit::event::{ElementState, KeyboardInput, VirtualKeyCode};
|
||||
use egui_winit::winit::event::{ElementState, KeyboardInput, VirtualKeyCode};
|
||||
|
||||
pub fn space_released(input: &KeyboardInput) -> bool {
|
||||
let keycode = input.virtual_keycode;
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
use egui_winit::winit::event::{ElementState, KeyboardInput, VirtualKeyCode};
|
||||
use gilrs::{Button, Event as GamepadEvent, EventType as GamepadEventType};
|
||||
use winit::event::{ElementState, KeyboardInput, VirtualKeyCode};
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct Joypad {
|
||||
|
|
31
src/main.rs
31
src/main.rs
|
@ -1,15 +1,16 @@
|
|||
use std::time::Instant;
|
||||
|
||||
use clap::{crate_authors, crate_description, crate_name, crate_version, Arg, Command};
|
||||
use egui_wgpu_backend::RenderPass;
|
||||
use egui_wgpu::renderer::RenderPass;
|
||||
use gb::gui::EmuMode;
|
||||
use gb::{emu, gui};
|
||||
use gilrs::Gilrs;
|
||||
use gui::GuiState;
|
||||
use rodio::{OutputStream, Sink};
|
||||
use tracing_subscriber::EnvFilter;
|
||||
use winit::event::{Event, WindowEvent};
|
||||
use winit::event_loop::EventLoop;
|
||||
|
||||
use egui_winit::winit::event::{Event, WindowEvent};
|
||||
use egui_winit::winit::event_loop::{EventLoop, EventLoopProxy};
|
||||
|
||||
const AUDIO_ENABLED: bool = true;
|
||||
|
||||
|
@ -48,7 +49,7 @@ fn main() {
|
|||
|
||||
// --Here lies a lot of winit + wgpu Boilerplate--
|
||||
let event_loop: EventLoop<Event<()>> = EventLoop::with_user_event();
|
||||
let window = gui::build_window(&event_loop).expect("build window");
|
||||
let window = gui::build_window(&event_loop).expect("create winit window");
|
||||
|
||||
let (instance, surface) = gui::create_surface(&window);
|
||||
let adapter = gui::request_adapter(&instance, &surface).expect("request adaptor");
|
||||
|
@ -59,7 +60,7 @@ fn main() {
|
|||
|
||||
let mut config = gui::surface_config(&window, format);
|
||||
surface.configure(&device, &config);
|
||||
let mut platform = gui::platform_desc(&window);
|
||||
let mut state = egui_winit::State::new(8192, &window);
|
||||
let mut render_pass = RenderPass::new(&device, format, 1);
|
||||
|
||||
// We interrupt your boiler plate to initialize the emulator so that
|
||||
|
@ -79,7 +80,9 @@ fn main() {
|
|||
let texture_size = gui::texture_size();
|
||||
let texture = gui::create_texture(&device, texture_size);
|
||||
gui::write_to_texture(&queue, &texture, emu::pixel_buf(&cpu), texture_size);
|
||||
let texture_id = gui::expose_texture_to_egui(&mut render_pass, &device, &texture);
|
||||
let texture_id = todo!("Expose Texture ID to egui");
|
||||
|
||||
render_pass.
|
||||
|
||||
// Load ROM if filepath was provided
|
||||
if let Some(path) = m.value_of("rom") {
|
||||
|
@ -116,14 +119,13 @@ fn main() {
|
|||
|
||||
// Set up state for the Immediate-mode GUI
|
||||
let mut app = GuiState::new(rom_title);
|
||||
let mut ctx = egui_winit::egui::Context::default();
|
||||
let mut last_key = gui::unused_key();
|
||||
|
||||
// used for egui animations
|
||||
let start_time = Instant::now();
|
||||
|
||||
event_loop.run(move |event, _, control_flow| {
|
||||
platform.handle_event(&event);
|
||||
|
||||
match event {
|
||||
Event::MainEventsCleared => {
|
||||
if app.quit {
|
||||
|
@ -147,8 +149,6 @@ fn main() {
|
|||
window.request_redraw();
|
||||
}
|
||||
Event::RedrawRequested(..) => {
|
||||
platform.update_time(start_time.elapsed().as_secs_f64());
|
||||
|
||||
let data = emu::pixel_buf(&cpu);
|
||||
gui::write_to_texture(&queue, &texture, data, texture_size);
|
||||
|
||||
|
@ -172,7 +172,7 @@ fn main() {
|
|||
let screen_descriptor = gui::create_screen_descriptor(&window, &config);
|
||||
|
||||
// Upload all resources for the GPU.
|
||||
render_pass.update_texture(&device, &queue, &platform.context().texture());
|
||||
render_pass.update_texture(&device, &queue, todo!(), todo!());
|
||||
render_pass.update_user_textures(&device, &queue);
|
||||
render_pass.update_buffers(&device, &queue, &paint_jobs, &screen_descriptor);
|
||||
|
||||
|
@ -192,7 +192,10 @@ fn main() {
|
|||
// Redraw egui
|
||||
output_frame.present();
|
||||
}
|
||||
Event::WindowEvent { event, .. } => match event {
|
||||
Event::WindowEvent { event, .. } => {
|
||||
let exclusive_use = state.on_event(&ctx, &event);
|
||||
if !exclusive_use {
|
||||
match event {
|
||||
WindowEvent::Resized(size) => {
|
||||
config.width = size.width;
|
||||
config.height = size.height;
|
||||
|
@ -203,7 +206,9 @@ fn main() {
|
|||
}
|
||||
WindowEvent::KeyboardInput { input, .. } => last_key = input,
|
||||
_ => {}
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
});
|
||||
|
|
Loading…
Reference in New Issue