Refactor lcd -> gpu

Former-commit-id: c12be139770922bac55490c76348f5406fc00f07
This commit is contained in:
Michel Heily 2019-07-16 01:21:11 +03:00
parent 876cdfdcb3
commit 1f074e20ad
6 changed files with 43 additions and 47 deletions

View file

@ -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;

View file

@ -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)));

View file

@ -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();

View file

@ -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);
// }

View file

@ -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;

View file

@ -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;