Refactor lcd -> gpu
Former-commit-id: c12be139770922bac55490c76348f5406fc00f07
This commit is contained in:
parent
876cdfdcb3
commit
1f074e20ad
|
@ -2,7 +2,7 @@ use crate::arm7tdmi::bus::Bus;
|
|||
use crate::arm7tdmi::{Addr, CpuState};
|
||||
use crate::disass::Disassembler;
|
||||
use crate::ioregs::consts::*;
|
||||
use crate::lcd::*;
|
||||
use crate::gpu::*;
|
||||
use crate::GBAError;
|
||||
|
||||
use super::palette_view::create_palette_view;
|
||||
|
|
|
@ -5,10 +5,10 @@ use sdl2::pixels::Color;
|
|||
use sdl2::rect::Point;
|
||||
|
||||
use crate::gba::GameBoyAdvance;
|
||||
use crate::lcd::Lcd;
|
||||
use crate::gpu::Gpu;
|
||||
|
||||
const SCREEN_WIDTH: u32 = Lcd::DISPLAY_WIDTH as u32;
|
||||
const SCREEN_HEIGHT: u32 = Lcd::DISPLAY_HEIGHT as u32;
|
||||
const SCREEN_WIDTH: u32 = Gpu::DISPLAY_WIDTH as u32;
|
||||
const SCREEN_HEIGHT: u32 = Gpu::DISPLAY_HEIGHT as u32;
|
||||
|
||||
pub fn create_render_view(gba: &GameBoyAdvance) {
|
||||
let sdl_context = sdl2::init().unwrap();
|
||||
|
@ -28,7 +28,7 @@ pub fn create_render_view(gba: &GameBoyAdvance) {
|
|||
match event {
|
||||
Event::Quit { .. } => break 'running,
|
||||
Event::MouseButtonDown { x, y, .. } => {
|
||||
println!("({},{}) {:x}", x, y, x + y * (Lcd::DISPLAY_WIDTH as i32));
|
||||
println!("({},{}) {:x}", x, y, x + y * (Gpu::DISPLAY_WIDTH as i32));
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
|
@ -37,10 +37,10 @@ pub fn create_render_view(gba: &GameBoyAdvance) {
|
|||
canvas.set_draw_color(Color::RGB(0xfa, 0xfa, 0xfa));
|
||||
canvas.clear();
|
||||
|
||||
for y in 0..Lcd::DISPLAY_HEIGHT {
|
||||
for x in 0..Lcd::DISPLAY_WIDTH {
|
||||
for y in 0..Gpu::DISPLAY_HEIGHT {
|
||||
for x in 0..Gpu::DISPLAY_WIDTH {
|
||||
let index = (x as usize) + (y as usize) * (256 as usize);
|
||||
let color = gba.lcd.pixeldata[index];
|
||||
let color = gba.gpu.pixeldata[index];
|
||||
let rgb24: Color = color.into();
|
||||
canvas.set_draw_color(rgb24);
|
||||
canvas.draw_point(Point::from((x as i32, y as i32)));
|
||||
|
|
|
@ -8,7 +8,7 @@ use sdl2::render::Canvas;
|
|||
use crate::arm7tdmi::bus::Bus;
|
||||
use crate::gba::GameBoyAdvance;
|
||||
use crate::ioregs::consts::*;
|
||||
use crate::lcd::*;
|
||||
use crate::gpu::*;
|
||||
use crate::palette::*;
|
||||
use crate::sysbus::SysBus;
|
||||
|
||||
|
@ -31,15 +31,15 @@ fn draw_tile(
|
|||
let color = match pixel_format {
|
||||
PixelFormat::BPP4 => {
|
||||
let index =
|
||||
gba.lcd
|
||||
gba.gpu
|
||||
.read_pixel_index(&gba.sysbus, tile_addr, x, y, 4, pixel_format);
|
||||
gba.lcd.get_palette_color(&gba.sysbus, index as u32, 0)
|
||||
gba.gpu.get_palette_color(&gba.sysbus, index as u32, 3)
|
||||
}
|
||||
PixelFormat::BPP8 => {
|
||||
let index =
|
||||
gba.lcd
|
||||
gba.gpu
|
||||
.read_pixel_index(&gba.sysbus, tile_addr, x, y, 8, pixel_format);
|
||||
gba.lcd.get_palette_color(&gba.sysbus, index as u32, 0)
|
||||
gba.gpu.get_palette_color(&gba.sysbus, index as u32, 0)
|
||||
}
|
||||
};
|
||||
let (r, g, b) = color.get_rgb24();
|
||||
|
|
16
src/gba.rs
16
src/gba.rs
|
@ -5,7 +5,7 @@ use super::cartridge::Cartridge;
|
|||
use super::dma::DmaChannel;
|
||||
use super::interrupt::*;
|
||||
use super::ioregs::consts::*;
|
||||
use super::lcd::*;
|
||||
use super::gpu::*;
|
||||
use super::sysbus::SysBus;
|
||||
|
||||
use super::{EmuIoDev, GBAError, GBAResult};
|
||||
|
@ -15,7 +15,7 @@ pub struct GameBoyAdvance {
|
|||
pub sysbus: SysBus,
|
||||
|
||||
// io devices
|
||||
pub lcd: Lcd,
|
||||
pub gpu: Gpu,
|
||||
pub dma0: DmaChannel,
|
||||
pub dma1: DmaChannel,
|
||||
pub dma2: DmaChannel,
|
||||
|
@ -32,7 +32,7 @@ impl GameBoyAdvance {
|
|||
cpu: cpu,
|
||||
sysbus: sysbus,
|
||||
|
||||
lcd: Lcd::new(),
|
||||
gpu: Gpu::new(),
|
||||
dma0: DmaChannel::new(REG_DMA0SAD, REG_DMA0DAD, REG_DMA0DAD),
|
||||
dma1: DmaChannel::new(REG_DMA1SAD, REG_DMA1DAD, REG_DMA1DAD),
|
||||
dma2: DmaChannel::new(REG_DMA2SAD, REG_DMA2DAD, REG_DMA2DAD),
|
||||
|
@ -49,7 +49,7 @@ impl GameBoyAdvance {
|
|||
self.cpu.step_one(&mut self.sysbus).unwrap();
|
||||
let new_cycles = self.cpu.cycles - previous_cycles;
|
||||
|
||||
self.lcd.step(new_cycles, &mut self.sysbus);
|
||||
self.gpu.step(new_cycles, &mut self.sysbus);
|
||||
cycles += new_cycles;
|
||||
|
||||
if n <= cycles {
|
||||
|
@ -59,10 +59,10 @@ impl GameBoyAdvance {
|
|||
}
|
||||
|
||||
pub fn frame(&mut self) {
|
||||
while self.lcd.state == LcdState::VBlank {
|
||||
while self.gpu.state == GpuState::VBlank {
|
||||
self.emulate();
|
||||
}
|
||||
while self.lcd.state != LcdState::VBlank {
|
||||
while self.gpu.state != GpuState::VBlank {
|
||||
self.emulate();
|
||||
}
|
||||
}
|
||||
|
@ -71,7 +71,7 @@ impl GameBoyAdvance {
|
|||
let previous_cycles = self.cpu.cycles;
|
||||
self.cpu.step(&mut self.sysbus).unwrap();
|
||||
let cycles = self.cpu.cycles - previous_cycles;
|
||||
self.lcd.step(cycles, &mut self.sysbus);
|
||||
self.gpu.step(cycles, &mut self.sysbus);
|
||||
}
|
||||
|
||||
fn interrupts_disabled(&self) -> bool {
|
||||
|
@ -111,7 +111,7 @@ impl GameBoyAdvance {
|
|||
// cycles += dma_cycles;
|
||||
|
||||
/* let (_, irq) = */
|
||||
self.lcd.step(cycles, &mut self.sysbus);
|
||||
self.gpu.step(cycles, &mut self.sysbus);
|
||||
// if let Some(irq) = irq {
|
||||
// self.request_irq(irq);
|
||||
// }
|
||||
|
|
|
@ -1,13 +1,9 @@
|
|||
use std::io::Cursor;
|
||||
use std::io::{Seek, SeekFrom};
|
||||
|
||||
use super::arm7tdmi::{Addr, Bus};
|
||||
use super::ioregs::consts::*;
|
||||
use super::palette::{Palette, PixelFormat, Rgb15};
|
||||
use super::*;
|
||||
|
||||
use crate::bit::BitIndex;
|
||||
use crate::byteorder::{LittleEndian, ReadBytesExt};
|
||||
use crate::num::FromPrimitive;
|
||||
|
||||
const VRAM_ADDR: Addr = 0x0600_0000;
|
||||
|
@ -127,34 +123,34 @@ impl BgControl {
|
|||
|
||||
pub fn tile_format(&self) -> (u32, PixelFormat) {
|
||||
if self.palette256 {
|
||||
(2 * Lcd::TILE_SIZE, PixelFormat::BPP8)
|
||||
(2 * Gpu::TILE_SIZE, PixelFormat::BPP8)
|
||||
} else {
|
||||
(Lcd::TILE_SIZE, PixelFormat::BPP4)
|
||||
(Gpu::TILE_SIZE, PixelFormat::BPP4)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq, Copy, Clone)]
|
||||
pub enum LcdState {
|
||||
pub enum GpuState {
|
||||
HDraw = 0,
|
||||
HBlank,
|
||||
VBlank,
|
||||
}
|
||||
impl Default for LcdState {
|
||||
fn default() -> LcdState {
|
||||
LcdState::HDraw
|
||||
impl Default for GpuState {
|
||||
fn default() -> GpuState {
|
||||
GpuState::HDraw
|
||||
}
|
||||
}
|
||||
use LcdState::*;
|
||||
use GpuState::*;
|
||||
|
||||
pub struct Lcd {
|
||||
pub struct Gpu {
|
||||
cycles: usize,
|
||||
pub pixeldata: [Rgb15; 256 * 256],
|
||||
pub state: LcdState,
|
||||
pub state: GpuState,
|
||||
pub current_scanline: usize, // VCOUNT
|
||||
}
|
||||
|
||||
impl Lcd {
|
||||
impl Gpu {
|
||||
pub const DISPLAY_WIDTH: usize = 240;
|
||||
pub const DISPLAY_HEIGHT: usize = 160;
|
||||
|
||||
|
@ -167,8 +163,8 @@ impl Lcd {
|
|||
|
||||
pub const TILE_SIZE: u32 = 0x20;
|
||||
|
||||
pub fn new() -> Lcd {
|
||||
Lcd {
|
||||
pub fn new() -> Gpu {
|
||||
Gpu {
|
||||
state: HDraw,
|
||||
current_scanline: 0,
|
||||
cycles: 0,
|
||||
|
@ -349,9 +345,9 @@ impl Lcd {
|
|||
}
|
||||
}
|
||||
|
||||
// *TODO* Running the Lcd step by step causes a massive performance impact, so for now not treat it as an emulated IO device.
|
||||
// *TODO* Running the Gpu step by step causes a massive performance impact, so for now not treat it as an emulated IO device.
|
||||
|
||||
impl EmuIoDev for Lcd {
|
||||
impl EmuIoDev for Gpu {
|
||||
fn step(&mut self, cycles: usize, sysbus: &mut SysBus) -> (usize, Option<Interrupt>) {
|
||||
self.cycles += cycles;
|
||||
|
||||
|
@ -367,11 +363,11 @@ impl EmuIoDev for Lcd {
|
|||
|
||||
match self.state {
|
||||
HDraw => {
|
||||
if self.cycles > Lcd::CYCLES_HDRAW {
|
||||
if self.cycles > Gpu::CYCLES_HDRAW {
|
||||
self.current_scanline += 1;
|
||||
self.cycles -= Lcd::CYCLES_HDRAW;
|
||||
self.cycles -= Gpu::CYCLES_HDRAW;
|
||||
|
||||
let (new_state, irq) = if self.current_scanline < Lcd::DISPLAY_HEIGHT {
|
||||
let (new_state, irq) = if self.current_scanline < Gpu::DISPLAY_HEIGHT {
|
||||
self.scanline(sysbus);
|
||||
// HBlank
|
||||
dispstat.hblank_flag = true;
|
||||
|
@ -396,8 +392,8 @@ impl EmuIoDev for Lcd {
|
|||
}
|
||||
}
|
||||
HBlank => {
|
||||
if self.cycles > Lcd::CYCLES_HBLANK {
|
||||
self.cycles -= Lcd::CYCLES_HBLANK;
|
||||
if self.cycles > Gpu::CYCLES_HBLANK {
|
||||
self.cycles -= Gpu::CYCLES_HBLANK;
|
||||
self.state = HDraw;
|
||||
dispstat.hblank_flag = false;
|
||||
self.update_regs(dispstat, sysbus);
|
||||
|
@ -405,8 +401,8 @@ impl EmuIoDev for Lcd {
|
|||
}
|
||||
}
|
||||
VBlank => {
|
||||
if self.cycles > Lcd::CYCLES_VBLANK {
|
||||
self.cycles -= Lcd::CYCLES_VBLANK;
|
||||
if self.cycles > Gpu::CYCLES_VBLANK {
|
||||
self.cycles -= Gpu::CYCLES_VBLANK;
|
||||
self.state = HDraw;
|
||||
dispstat.vblank_flag = false;
|
||||
self.current_scanline = 0;
|
|
@ -15,6 +15,7 @@ extern crate ansi_term;
|
|||
extern crate colored; // not needed in Rust 2018
|
||||
|
||||
pub mod arm7tdmi;
|
||||
pub mod gpu;
|
||||
pub mod cartridge;
|
||||
pub mod debugger;
|
||||
pub mod disass;
|
||||
|
@ -26,7 +27,6 @@ pub use interrupt::Interrupt;
|
|||
pub mod gba;
|
||||
pub use gba::GameBoyAdvance;
|
||||
pub mod dma;
|
||||
pub mod lcd;
|
||||
pub mod palette;
|
||||
pub mod util;
|
||||
|
||||
|
|
Reference in a new issue