mirror of
https://github.com/FranLMSP/snes.git
synced 2026-01-01 07:21:35 -05:00
Show game framebuffer (#8)
This commit is contained in:
2
.github/workflows/rust.yml
vendored
2
.github/workflows/rust.yml
vendored
@@ -17,7 +17,7 @@ jobs:
|
|||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v3
|
||||||
- name: Install dependencies
|
- name: Install dependencies
|
||||||
run: sudo apt install libgtk-3-dev
|
run: sudo apt update && sudo apt install libgtk-3-dev
|
||||||
- name: Build
|
- name: Build
|
||||||
run: cargo build --verbose
|
run: cargo build --verbose
|
||||||
- name: Run tests
|
- name: Run tests
|
||||||
|
|||||||
@@ -1,4 +1,6 @@
|
|||||||
use super::registers::PPURegisters;
|
use super::registers::{PPURegisters, MAX_TV_HEIGHT, MAX_TV_WIDTH};
|
||||||
|
|
||||||
|
const FRAMEBUFFER_SIZE: usize = MAX_TV_HEIGHT * MAX_TV_WIDTH * 4;
|
||||||
|
|
||||||
pub struct PPU {
|
pub struct PPU {
|
||||||
framebuffer: Vec<u8>,
|
framebuffer: Vec<u8>,
|
||||||
@@ -10,7 +12,7 @@ pub struct PPU {
|
|||||||
impl PPU {
|
impl PPU {
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
Self {
|
Self {
|
||||||
framebuffer: vec![],
|
framebuffer: vec![0; FRAMEBUFFER_SIZE],
|
||||||
registers: PPURegisters::new(),
|
registers: PPURegisters::new(),
|
||||||
was_vblank_nmi_set: false,
|
was_vblank_nmi_set: false,
|
||||||
is_irq_set: false,
|
is_irq_set: false,
|
||||||
@@ -46,7 +48,7 @@ impl PPU {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn framebuffer(&self) -> &Vec<u8> {
|
pub fn framebuffer(&self) -> &[u8] {
|
||||||
&self.framebuffer
|
&self.framebuffer
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -88,6 +88,9 @@ pub const STAT78: u16 = 0x213F; // PPU1 Status and PPU1 Version Number
|
|||||||
pub const MAX_BG_WIDTH: usize = 16 * 64;
|
pub const MAX_BG_WIDTH: usize = 16 * 64;
|
||||||
pub const MAX_BG_HEIGHT: usize = 16 * 64;
|
pub const MAX_BG_HEIGHT: usize = 16 * 64;
|
||||||
|
|
||||||
|
pub const MAX_TV_WIDTH: usize = 512;
|
||||||
|
pub const MAX_TV_HEIGHT: usize = 448;
|
||||||
|
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Copy, Clone)]
|
#[derive(Debug, PartialEq, Copy, Clone)]
|
||||||
pub enum TileSize {
|
pub enum TileSize {
|
||||||
|
|||||||
@@ -1,10 +1,11 @@
|
|||||||
use crate::emu_state::debug_options::DebugOptions;
|
use crate::emu_state::debug_options::DebugOptions;
|
||||||
use crate::emu_state::emulation::EmulationState;
|
use crate::emu_state::emulation::EmulationState;
|
||||||
|
use eframe::epaint::TextureHandle;
|
||||||
|
|
||||||
pub struct AppState {
|
pub struct AppState {
|
||||||
pub debug_options: DebugOptions,
|
pub debug_options: DebugOptions,
|
||||||
pub emulation_state: EmulationState,
|
pub emulation_state: EmulationState,
|
||||||
|
pub game_tv_texture: Option<TextureHandle>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl AppState {
|
impl AppState {
|
||||||
@@ -12,6 +13,7 @@ impl AppState {
|
|||||||
Self {
|
Self {
|
||||||
debug_options: DebugOptions::new(),
|
debug_options: DebugOptions::new(),
|
||||||
emulation_state: EmulationState::new(),
|
emulation_state: EmulationState::new(),
|
||||||
|
game_tv_texture: None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
53
snes-frontend/src/emu_ui/game.rs
Normal file
53
snes-frontend/src/emu_ui/game.rs
Normal file
@@ -0,0 +1,53 @@
|
|||||||
|
use eframe::egui;
|
||||||
|
use eframe::{egui::Context, epaint::ColorImage};
|
||||||
|
use eframe::egui::{TextureOptions, Ui};
|
||||||
|
use eframe::epaint::{Vec2, TextureHandle};
|
||||||
|
use snes_core::ppu::registers::{
|
||||||
|
MAX_TV_WIDTH,
|
||||||
|
MAX_TV_HEIGHT,
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
pub fn build_game_window(
|
||||||
|
ctx: &egui::Context,
|
||||||
|
game_tv_texture: &mut Option<TextureHandle>,
|
||||||
|
framebuffer: &[u8],
|
||||||
|
) {
|
||||||
|
egui::Window::new("TV")
|
||||||
|
.collapsible(false)
|
||||||
|
.show(ctx, |ui| {
|
||||||
|
paint_game_texture(ui, game_tv_texture, framebuffer);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn initialize_game_texture(ctx: &Context, game_tv_texture: &mut Option<TextureHandle>) {
|
||||||
|
if game_tv_texture.is_none() {
|
||||||
|
println!("Initializing Game TV texture");
|
||||||
|
let _ = game_tv_texture.insert(
|
||||||
|
ctx.load_texture(
|
||||||
|
"Game TV texture",
|
||||||
|
ColorImage::default(),
|
||||||
|
Default::default(),
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn paint_game_texture(ui: &mut Ui, texture: &mut Option<TextureHandle>, framebuffer: &[u8]) {
|
||||||
|
if let Some(txt) = texture {
|
||||||
|
txt.set(
|
||||||
|
ColorImage::from_rgba_premultiplied([MAX_TV_WIDTH, MAX_TV_HEIGHT], framebuffer),
|
||||||
|
TextureOptions::default(),
|
||||||
|
);
|
||||||
|
let (whole_rect, _) =
|
||||||
|
ui.allocate_exact_size(
|
||||||
|
Vec2::from([(MAX_TV_WIDTH) as f32, (MAX_TV_HEIGHT) as f32]),
|
||||||
|
egui::Sense::focusable_noninteractive(),
|
||||||
|
);
|
||||||
|
egui::Image::new((
|
||||||
|
txt.id(),
|
||||||
|
txt.size_vec2(),
|
||||||
|
))
|
||||||
|
.paint_at(ui, whole_rect);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,2 +1,3 @@
|
|||||||
pub mod menu;
|
pub mod menu;
|
||||||
|
pub mod game;
|
||||||
pub mod debug;
|
pub mod debug;
|
||||||
|
|||||||
@@ -24,8 +24,14 @@ impl eframe::App for SnesEmulatorApp {
|
|||||||
egui::CentralPanel::default().show(ctx, |ui| {
|
egui::CentralPanel::default().show(ctx, |ui| {
|
||||||
emu_ui::menu::build_menu_bar(&mut self.emulator, ui, &mut self.state);
|
emu_ui::menu::build_menu_bar(&mut self.emulator, ui, &mut self.state);
|
||||||
ui.separator();
|
ui.separator();
|
||||||
// ui::game::build_game_window(ctx);
|
|
||||||
});
|
});
|
||||||
|
emu_ui::game::initialize_game_texture(ctx, &mut self.state.game_tv_texture);
|
||||||
|
emu_ui::game::build_game_window(
|
||||||
|
ctx,
|
||||||
|
&mut self.state.game_tv_texture,
|
||||||
|
self.emulator.bus.ppu.framebuffer(),
|
||||||
|
);
|
||||||
|
emu_ui::debug::build_all_debug_options(ctx, &mut self.state.debug_options, &mut self.state.emulation_state, &mut self.emulator);
|
||||||
if !self.state.emulation_state.is_paused {
|
if !self.state.emulation_state.is_paused {
|
||||||
if self.state.emulation_state.one_tick_per_frame {
|
if self.state.emulation_state.one_tick_per_frame {
|
||||||
self.emulator.tick();
|
self.emulator.tick();
|
||||||
@@ -33,7 +39,6 @@ impl eframe::App for SnesEmulatorApp {
|
|||||||
self.emulator.loop_frame();
|
self.emulator.loop_frame();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
emu_ui::debug::build_all_debug_options(ctx, &mut self.state.debug_options, &mut self.state.emulation_state, &mut self.emulator);
|
|
||||||
ctx.request_repaint();
|
ctx.request_repaint();
|
||||||
self.frame_limit.limit();
|
self.frame_limit.limit();
|
||||||
self.frame_limit.reset_timer();
|
self.frame_limit.reset_timer();
|
||||||
|
|||||||
Reference in New Issue
Block a user