feat: add pixels-rs and winit as dependencies
This commit is contained in:
parent
207bcfea30
commit
2fc7ac3833
File diff suppressed because it is too large
Load Diff
|
@ -7,3 +7,7 @@ edition = "2018"
|
|||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
anyhow = "1.0.38"
|
||||
pixels = "0.2.0"
|
||||
winit = "0.24.0"
|
||||
winit_input_helper = "0.9.0"
|
||||
|
|
|
@ -10,7 +10,7 @@ use super::work_ram::{VariableWorkRAM, WorkRAM};
|
|||
pub struct Bus {
|
||||
boot: Option<[u8; 256]>, // Boot ROM is 256b long
|
||||
cartridge: Option<Cartridge>,
|
||||
ppu: PPU,
|
||||
pub ppu: PPU,
|
||||
wram: WorkRAM,
|
||||
vwram: VariableWorkRAM,
|
||||
timer: Timer,
|
||||
|
|
38
src/cpu.rs
38
src/cpu.rs
|
@ -1,10 +1,11 @@
|
|||
use super::bus::Bus;
|
||||
use super::instruction::Instruction;
|
||||
use super::instruction::{Cycles, Instruction};
|
||||
use super::ppu::PPU;
|
||||
use std::fmt::{Display, Formatter, Result as FmtResult};
|
||||
|
||||
#[derive(Debug, Clone, Default)]
|
||||
pub struct Cpu {
|
||||
bus: Bus,
|
||||
pub bus: Bus,
|
||||
reg: Registers,
|
||||
flags: Flags,
|
||||
ime: bool,
|
||||
|
@ -61,32 +62,11 @@ impl Cpu {
|
|||
}
|
||||
|
||||
pub fn decode(&mut self, opcode: u8) -> Instruction {
|
||||
let tmp = Instruction::from_byte(self, opcode);
|
||||
|
||||
let a = self.register(Register::A);
|
||||
let flag: Flags = self.register(Register::Flag).into();
|
||||
let bc = self.register_pair(RegisterPair::BC);
|
||||
let de = self.register_pair(RegisterPair::DE);
|
||||
let hl = self.register_pair(RegisterPair::HL);
|
||||
let sp = self.register_pair(RegisterPair::SP);
|
||||
|
||||
// println!(
|
||||
// "A: {:#04X} | BC: {:#06X} | DE: {:#06X} | HL: {:#06X} | SP: {:#06X} | {}",
|
||||
// a, bc, de, hl, sp, flag
|
||||
// );
|
||||
|
||||
// Get info from serial port
|
||||
// if self.bus.read_byte(0xFF02) == 0x81 {
|
||||
// let c = self.bus.read_byte(0xFF01) as char;
|
||||
// self.bus.write_byte(0xFF02, 0x00);
|
||||
// print!("TEST RESULT!: {}", c);
|
||||
// }
|
||||
|
||||
tmp
|
||||
Instruction::from_byte(self, opcode)
|
||||
}
|
||||
|
||||
pub fn execute(&mut self, instruction: Instruction) {
|
||||
Instruction::execute(self, instruction);
|
||||
pub fn execute(&mut self, instruction: Instruction) -> Cycles {
|
||||
Instruction::execute(self, instruction)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -119,6 +99,12 @@ impl Cpu {
|
|||
}
|
||||
}
|
||||
|
||||
impl Cpu {
|
||||
pub fn get_ppu(&mut self) -> &mut PPU {
|
||||
&mut self.bus.ppu
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
enum State {
|
||||
Execute,
|
||||
|
|
98
src/main.rs
98
src/main.rs
|
@ -1,20 +1,98 @@
|
|||
use anyhow::{anyhow, Result};
|
||||
use gb::cpu::Cpu as LR35902;
|
||||
use pixels::{Pixels, SurfaceTexture};
|
||||
use std::io::Write;
|
||||
use winit::{
|
||||
dpi::LogicalSize,
|
||||
event::{Event, VirtualKeyCode},
|
||||
event_loop::{ControlFlow, EventLoop},
|
||||
window::Window,
|
||||
window::WindowBuilder,
|
||||
};
|
||||
use winit_input_helper::WinitInputHelper;
|
||||
|
||||
fn main() {
|
||||
// 160 x 144
|
||||
const GB_WIDTH: u32 = 160;
|
||||
const GB_HEIGHT: u32 = 144;
|
||||
|
||||
fn main() -> Result<()> {
|
||||
let event_loop = EventLoop::new();
|
||||
let mut input = WinitInputHelper::new();
|
||||
let window = create_window(&event_loop)?;
|
||||
let mut pixels = create_pixels(&window)?;
|
||||
|
||||
let out = Box::leak(Box::new(std::io::stdout()));
|
||||
let mut out_handle = out.lock();
|
||||
let mut game_boy = LR35902::new();
|
||||
|
||||
game_boy.load_cartridge("bin/cpu_instrs.gb");
|
||||
|
||||
loop {
|
||||
let pc = game_boy.register_pair(gb::cpu::RegisterPair::PC);
|
||||
event_loop.run(move |event, _, control_flow| {
|
||||
if let Event::RedrawRequested(_) = event {
|
||||
let ppu = game_boy.get_ppu();
|
||||
let frame = pixels.get_frame();
|
||||
|
||||
ppu.draw(frame);
|
||||
|
||||
if pixels
|
||||
.render()
|
||||
.map_err(|e| anyhow!("pixels.render() failed: {}", e))
|
||||
.is_err()
|
||||
{
|
||||
*control_flow = ControlFlow::Exit;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if input.update(&event) {
|
||||
if input.key_pressed(VirtualKeyCode::Escape) || input.quit() {
|
||||
*control_flow = ControlFlow::Exit;
|
||||
return;
|
||||
}
|
||||
|
||||
if let Some(size) = input.window_resized() {
|
||||
pixels.resize(size.width, size.height);
|
||||
}
|
||||
|
||||
// Emulation
|
||||
let addr = game_boy.register_pair(gb::cpu::RegisterPair::PC);
|
||||
|
||||
let opcode = game_boy.fetch();
|
||||
let instruction = game_boy.decode(opcode);
|
||||
let _cycles = game_boy.execute(instruction);
|
||||
window.request_redraw();
|
||||
|
||||
println!(
|
||||
"Addr: {:#06X} | Opcode: {:#04X} | Instr: {:X?}",
|
||||
pc, opcode, instruction
|
||||
);
|
||||
|
||||
game_boy.execute(instruction);
|
||||
write!(
|
||||
out_handle,
|
||||
"Addr: {:#06X} | Opcode: {:#04X} | Instr: {:X?}\n",
|
||||
addr, opcode, instruction
|
||||
)
|
||||
.unwrap();
|
||||
}
|
||||
});
|
||||
|
||||
// loop {
|
||||
// let pc = game_boy.register_pair(gb::cpu::RegisterPair::PC);
|
||||
// let opcode = game_boy.fetch();
|
||||
// let instruction = game_boy.decode(opcode);
|
||||
|
||||
// let _cycles = game_boy.execute(instruction);
|
||||
|
||||
// let ppu = game_boy.get_ppu();
|
||||
// ppu.step();
|
||||
// }
|
||||
}
|
||||
|
||||
pub fn create_window(event_loop: &EventLoop<()>) -> Result<Window> {
|
||||
let size = LogicalSize::new(GB_WIDTH as f64, GB_HEIGHT as f64);
|
||||
Ok(WindowBuilder::new()
|
||||
.with_title("DMG-1 Game Boy")
|
||||
.with_inner_size(size)
|
||||
.with_min_inner_size(size)
|
||||
.build(&event_loop)?)
|
||||
}
|
||||
|
||||
pub fn create_pixels(window: &Window) -> Result<Pixels<Window>> {
|
||||
let window_size = window.inner_size();
|
||||
let surface_texture = SurfaceTexture::new(window_size.width, window_size.height, window);
|
||||
Ok(Pixels::new(GB_WIDTH, GB_HEIGHT, surface_texture)?)
|
||||
}
|
||||
|
|
11
src/ppu.rs
11
src/ppu.rs
|
@ -7,6 +7,17 @@ pub struct PPU {
|
|||
pub stat: LCDStatus,
|
||||
}
|
||||
|
||||
impl PPU {
|
||||
pub fn step(&mut self) {}
|
||||
|
||||
pub fn draw(&self, frame: &mut [u8]) {
|
||||
for (_i, pixel) in frame.chunks_exact_mut(4).enumerate() {
|
||||
let rgba: [u8; 4] = [0xFF, 0xFF, 0xFF, 0xFF];
|
||||
pixel.copy_from_slice(&rgba);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for PPU {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
|
|
Loading…
Reference in New Issue