feat: add pixels-rs and winit as dependencies
This commit is contained in:
		
							
								
								
									
										1670
									
								
								Cargo.lock
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										1670
									
								
								Cargo.lock
									
									
									
										generated
									
									
									
								
							
										
											
												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, | ||||
|   | ||||
							
								
								
									
										102
									
								
								src/main.rs
									
									
									
									
									
								
							
							
						
						
									
										102
									
								
								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); | ||||
|         let opcode = game_boy.fetch(); | ||||
|         let instruction = game_boy.decode(opcode); | ||||
|     event_loop.run(move |event, _, control_flow| { | ||||
|         if let Event::RedrawRequested(_) = event { | ||||
|             let ppu = game_boy.get_ppu(); | ||||
|             let frame = pixels.get_frame(); | ||||
|  | ||||
|         println!( | ||||
|             "Addr: {:#06X} | Opcode: {:#04X} | Instr: {:X?}", | ||||
|             pc, opcode, instruction | ||||
|         ); | ||||
|             ppu.draw(frame); | ||||
|  | ||||
|         game_boy.execute(instruction); | ||||
|     } | ||||
|             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(); | ||||
|  | ||||
|             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 { | ||||
|   | ||||
		Reference in New Issue
	
	Block a user