gpu: refactor: Move Rgb15 to its own module
Former-commit-id: d83748802435594573255171ae888efd6f406ad3
This commit is contained in:
parent
615515fcea
commit
118beeb4b7
6 changed files with 145 additions and 207 deletions
src
|
@ -10,6 +10,8 @@ mod mosaic;
|
||||||
mod obj;
|
mod obj;
|
||||||
use obj::ObjInfo;
|
use obj::ObjInfo;
|
||||||
mod sfx;
|
mod sfx;
|
||||||
|
mod rgb15;
|
||||||
|
pub use rgb15::Rgb15;
|
||||||
|
|
||||||
pub mod regs;
|
pub mod regs;
|
||||||
pub use regs::*;
|
pub use regs::*;
|
||||||
|
@ -28,41 +30,6 @@ const CYCLES_VBLANK: usize = 83776;
|
||||||
|
|
||||||
pub const TILE_SIZE: u32 = 0x20;
|
pub const TILE_SIZE: u32 = 0x20;
|
||||||
|
|
||||||
// TODO - remove the one in palette.rs
|
|
||||||
bitfield! {
|
|
||||||
#[derive(Copy, Clone, Default, PartialEq)]
|
|
||||||
pub struct Rgb15(u16);
|
|
||||||
impl Debug;
|
|
||||||
pub r, set_r: 4, 0;
|
|
||||||
pub g, set_g: 9, 5;
|
|
||||||
pub b, set_b: 14, 10;
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Rgb15 {
|
|
||||||
pub const BLACK: Rgb15 = Rgb15(0);
|
|
||||||
pub const WHITE: Rgb15 = Rgb15(0x7fff);
|
|
||||||
pub const TRANSPARENT: Rgb15 = Rgb15(0x8000);
|
|
||||||
|
|
||||||
pub fn to_rgb24(&self) -> u32 {
|
|
||||||
((self.r() as u32) << 19) | ((self.g() as u32) << 11) | ((self.b() as u32) << 3)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn from_rgb(r: u16, g: u16, b: u16) -> Rgb15 {
|
|
||||||
let mut c = Rgb15(0);
|
|
||||||
c.set_r(r);
|
|
||||||
c.set_g(g);
|
|
||||||
c.set_b(b);
|
|
||||||
c
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn get_rgb(&self) -> (u16, u16, u16) {
|
|
||||||
(self.r(), self.g(), self.b())
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn is_transparent(&self) -> bool {
|
|
||||||
self.0 == 0x8000
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, Primitive, Copy, Clone)]
|
#[derive(Debug, Primitive, Copy, Clone)]
|
||||||
pub enum PixelFormat {
|
pub enum PixelFormat {
|
||||||
|
|
37
src/core/gpu/rgb15.rs
Normal file
37
src/core/gpu/rgb15.rs
Normal file
|
@ -0,0 +1,37 @@
|
||||||
|
//! Helper type to deal with the GBA's 15bit color
|
||||||
|
|
||||||
|
bitfield! {
|
||||||
|
#[repr(transparent)]
|
||||||
|
#[derive(Copy, Clone, Default, PartialEq)]
|
||||||
|
pub struct Rgb15(u16);
|
||||||
|
impl Debug;
|
||||||
|
pub r, set_r: 4, 0;
|
||||||
|
pub g, set_g: 9, 5;
|
||||||
|
pub b, set_b: 14, 10;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Rgb15 {
|
||||||
|
pub const BLACK: Rgb15 = Rgb15(0);
|
||||||
|
pub const WHITE: Rgb15 = Rgb15(0x7fff);
|
||||||
|
pub const TRANSPARENT: Rgb15 = Rgb15(0x8000);
|
||||||
|
|
||||||
|
pub fn to_rgb24(&self) -> u32 {
|
||||||
|
((self.r() as u32) << 19) | ((self.g() as u32) << 11) | ((self.b() as u32) << 3)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn from_rgb(r: u16, g: u16, b: u16) -> Rgb15 {
|
||||||
|
let mut c = Rgb15(0);
|
||||||
|
c.set_r(r);
|
||||||
|
c.set_g(g);
|
||||||
|
c.set_b(b);
|
||||||
|
c
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_rgb(&self) -> (u16, u16, u16) {
|
||||||
|
(self.r(), self.g(), self.b())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn is_transparent(&self) -> bool {
|
||||||
|
self.0 == 0x8000
|
||||||
|
}
|
||||||
|
}
|
|
@ -12,7 +12,6 @@ pub mod gba;
|
||||||
pub use gba::GameBoyAdvance;
|
pub use gba::GameBoyAdvance;
|
||||||
pub mod dma;
|
pub mod dma;
|
||||||
pub mod keypad;
|
pub mod keypad;
|
||||||
pub mod palette;
|
|
||||||
pub mod timer;
|
pub mod timer;
|
||||||
|
|
||||||
use crate::debugger;
|
use crate::debugger;
|
||||||
|
|
|
@ -1,65 +0,0 @@
|
||||||
use std::fmt;
|
|
||||||
|
|
||||||
use byteorder::{LittleEndian, ReadBytesExt};
|
|
||||||
use std::io::Cursor;
|
|
||||||
|
|
||||||
#[derive(Debug, Copy, Clone, Default)]
|
|
||||||
pub struct Rgb15 {
|
|
||||||
pub r: u8,
|
|
||||||
pub g: u8,
|
|
||||||
pub b: u8,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<u16> for Rgb15 {
|
|
||||||
fn from(v: u16) -> Rgb15 {
|
|
||||||
use bit::BitIndex;
|
|
||||||
Rgb15 {
|
|
||||||
r: v.bit_range(0..5) as u8,
|
|
||||||
g: v.bit_range(5..10) as u8,
|
|
||||||
b: v.bit_range(10..15) as u8,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl fmt::Display for Rgb15 {
|
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
|
||||||
write!(f, "Rgb15({:#x},{:#x},{:#x})", self.r, self.g, self.b)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Rgb15 {
|
|
||||||
/// Convert 15-bit high color to a 24-bit true color.
|
|
||||||
pub fn get_rgb24(&self) -> (u8, u8, u8) {
|
|
||||||
(self.r << 3, self.g << 3, self.b << 3)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, Primitive, Copy, Clone)]
|
|
||||||
pub enum PixelFormat {
|
|
||||||
BPP4 = 0,
|
|
||||||
BPP8 = 1,
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct Palette {
|
|
||||||
pub bg_colors: [Rgb15; 256],
|
|
||||||
pub fg_colors: [Rgb15; 256],
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<&[u8]> for Palette {
|
|
||||||
fn from(bytes: &[u8]) -> Palette {
|
|
||||||
let mut rdr = Cursor::new(bytes);
|
|
||||||
|
|
||||||
let mut bg_colors: [Rgb15; 256] = [0.into(); 256];
|
|
||||||
for i in 0..256 {
|
|
||||||
bg_colors[i] = rdr.read_u16::<LittleEndian>().unwrap().into();
|
|
||||||
}
|
|
||||||
let mut fg_colors: [Rgb15; 256] = [0.into(); 256];
|
|
||||||
for i in 0..256 {
|
|
||||||
fg_colors[i] = rdr.read_u16::<LittleEndian>().unwrap().into();
|
|
||||||
}
|
|
||||||
Palette {
|
|
||||||
bg_colors,
|
|
||||||
fg_colors,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -10,7 +10,7 @@ use crate::core::GBAError;
|
||||||
use crate::disass::Disassembler;
|
use crate::disass::Disassembler;
|
||||||
use crate::{AudioInterface, InputInterface, VideoInterface};
|
use crate::{AudioInterface, InputInterface, VideoInterface};
|
||||||
|
|
||||||
use super::palette_view::create_palette_view;
|
// use super::palette_view::create_palette_view;
|
||||||
// use super::tile_view::create_tile_view;
|
// use super::tile_view::create_tile_view;
|
||||||
use super::{parser::Value, Debugger, DebuggerError, DebuggerResult};
|
use super::{parser::Value, Debugger, DebuggerError, DebuggerResult};
|
||||||
|
|
||||||
|
@ -54,7 +54,7 @@ pub enum Command {
|
||||||
Disass(DisassMode, Addr, u32),
|
Disass(DisassMode, Addr, u32),
|
||||||
AddBreakpoint(Addr),
|
AddBreakpoint(Addr),
|
||||||
DelBreakpoint(Addr),
|
DelBreakpoint(Addr),
|
||||||
PaletteView,
|
// PaletteView,
|
||||||
// TileView(u32),
|
// TileView(u32),
|
||||||
ClearBreakpoints,
|
ClearBreakpoints,
|
||||||
ListBreakpoints,
|
ListBreakpoints,
|
||||||
|
@ -170,7 +170,7 @@ impl Debugger {
|
||||||
println!("[{}] 0x{:08x}", i, b)
|
println!("[{}] 0x{:08x}", i, b)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
PaletteView => create_palette_view(&self.gba.sysbus.palette_ram.mem),
|
// PaletteView => create_palette_view(&self.gba.sysbus.palette_ram.mem),
|
||||||
// TileView(bg) => create_tile_view(bg, &self.gba),
|
// TileView(bg) => create_tile_view(bg, &self.gba),
|
||||||
Reset => {
|
Reset => {
|
||||||
println!("resetting cpu...");
|
println!("resetting cpu...");
|
||||||
|
@ -413,7 +413,7 @@ impl Debugger {
|
||||||
"breakdel [addr]",
|
"breakdel [addr]",
|
||||||
))),
|
))),
|
||||||
},
|
},
|
||||||
"palette-view" => Ok(Command::PaletteView),
|
// "palette-view" => Ok(Command::PaletteView),
|
||||||
// "tiles" => {
|
// "tiles" => {
|
||||||
// if args.len() != 1 {
|
// if args.len() != 1 {
|
||||||
// return Err(DebuggerError::InvalidCommandFormat("tile <bg>".to_string()));
|
// return Err(DebuggerError::InvalidCommandFormat("tile <bg>".to_string()));
|
||||||
|
|
|
@ -1,120 +1,120 @@
|
||||||
use sdl2::event::Event;
|
// use sdl2::event::Event;
|
||||||
use sdl2::pixels::Color;
|
// use sdl2::pixels::Color;
|
||||||
use sdl2::rect::{Point, Rect};
|
// use sdl2::rect::{Point, Rect};
|
||||||
use sdl2::render::Canvas;
|
// use sdl2::render::Canvas;
|
||||||
|
|
||||||
use crate::core::palette::{Palette, Rgb15};
|
// use crate::core::palette::{Palette, Rgb15};
|
||||||
|
|
||||||
const PALETTE_RECT_WIDTH: u32 = 20;
|
// const PALETTE_RECT_WIDTH: u32 = 20;
|
||||||
|
|
||||||
const SCREEN_WIDTH: u32 = 900;
|
// const SCREEN_WIDTH: u32 = 900;
|
||||||
const SCREEN_HEIGHT: u32 = 500;
|
// const SCREEN_HEIGHT: u32 = 500;
|
||||||
|
|
||||||
struct ColoredRect {
|
// struct ColoredRect {
|
||||||
index: usize,
|
// index: usize,
|
||||||
rect: Rect,
|
// rect: Rect,
|
||||||
color: Rgb15,
|
// color: Rgb15,
|
||||||
}
|
// }
|
||||||
|
|
||||||
impl ColoredRect {
|
// impl ColoredRect {
|
||||||
fn new(index: usize, x: i32, y: i32, c: Rgb15) -> ColoredRect {
|
// fn new(index: usize, x: i32, y: i32, c: Rgb15) -> ColoredRect {
|
||||||
ColoredRect {
|
// ColoredRect {
|
||||||
index: index,
|
// index: index,
|
||||||
rect: Rect::new(x, y, PALETTE_RECT_WIDTH, PALETTE_RECT_WIDTH),
|
// rect: Rect::new(x, y, PALETTE_RECT_WIDTH, PALETTE_RECT_WIDTH),
|
||||||
color: c,
|
// color: c,
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
|
||||||
fn draw(&self, canvas: &mut Canvas<sdl2::video::Window>) {
|
// fn draw(&self, canvas: &mut Canvas<sdl2::video::Window>) {
|
||||||
canvas.set_draw_color(Color::RGB(0, 0, 0));
|
// canvas.set_draw_color(Color::RGB(0, 0, 0));
|
||||||
canvas
|
// canvas
|
||||||
.fill_rect(Rect::new(
|
// .fill_rect(Rect::new(
|
||||||
self.rect.x() - 1,
|
// self.rect.x() - 1,
|
||||||
self.rect.y() - 1,
|
// self.rect.y() - 1,
|
||||||
PALETTE_RECT_WIDTH + 2,
|
// PALETTE_RECT_WIDTH + 2,
|
||||||
PALETTE_RECT_WIDTH + 2,
|
// PALETTE_RECT_WIDTH + 2,
|
||||||
))
|
// ))
|
||||||
.unwrap();
|
// .unwrap();
|
||||||
|
|
||||||
let (r, g, b) = self.color.get_rgb24();
|
// let (r, g, b) = self.color.get_rgb24();
|
||||||
canvas.set_draw_color(Color::RGB(r, g, b));
|
// canvas.set_draw_color(Color::RGB(r, g, b));
|
||||||
canvas.fill_rect(self.rect).unwrap();
|
// canvas.fill_rect(self.rect).unwrap();
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
|
||||||
pub fn create_palette_view(palette_ram: &[u8]) {
|
// pub fn create_palette_view(palette_ram: &[u8]) {
|
||||||
let palette = Palette::from(palette_ram);
|
// let palette = Palette::from(palette_ram);
|
||||||
|
|
||||||
let sdl_context = sdl2::init().unwrap();
|
// let sdl_context = sdl2::init().unwrap();
|
||||||
let video_subsystem = sdl_context.video().unwrap();
|
// let video_subsystem = sdl_context.video().unwrap();
|
||||||
|
|
||||||
let window = video_subsystem
|
// let window = video_subsystem
|
||||||
.window("PaletteView", SCREEN_WIDTH, SCREEN_HEIGHT)
|
// .window("PaletteView", SCREEN_WIDTH, SCREEN_HEIGHT)
|
||||||
.position_centered()
|
// .position_centered()
|
||||||
.build()
|
// .build()
|
||||||
.unwrap();
|
// .unwrap();
|
||||||
|
|
||||||
let mut canvas = window.into_canvas().build().unwrap();
|
// let mut canvas = window.into_canvas().build().unwrap();
|
||||||
|
|
||||||
canvas.set_draw_color(Color::RGB(0xfa, 0xfa, 0xfa));
|
// canvas.set_draw_color(Color::RGB(0xfa, 0xfa, 0xfa));
|
||||||
canvas.clear();
|
// canvas.clear();
|
||||||
|
|
||||||
let mut bg_colors: Vec<ColoredRect> = Vec::with_capacity(256);
|
// let mut bg_colors: Vec<ColoredRect> = Vec::with_capacity(256);
|
||||||
let mut fg_colors: Vec<ColoredRect> = Vec::with_capacity(256);
|
// let mut fg_colors: Vec<ColoredRect> = Vec::with_capacity(256);
|
||||||
|
|
||||||
let initial_x = 30u32;
|
// let initial_x = 30u32;
|
||||||
let mut y = 20u32;
|
// let mut y = 20u32;
|
||||||
let mut x = initial_x;
|
// let mut x = initial_x;
|
||||||
for i in 0..256 {
|
// for i in 0..256 {
|
||||||
bg_colors.push(ColoredRect::new(
|
// bg_colors.push(ColoredRect::new(
|
||||||
i,
|
// i,
|
||||||
x as i32,
|
// x as i32,
|
||||||
y as i32,
|
// y as i32,
|
||||||
palette.bg_colors[i],
|
// palette.bg_colors[i],
|
||||||
));
|
// ));
|
||||||
fg_colors.push(ColoredRect::new(
|
// fg_colors.push(ColoredRect::new(
|
||||||
i,
|
// i,
|
||||||
x as i32 + 450,
|
// x as i32 + 450,
|
||||||
y as i32,
|
// y as i32,
|
||||||
palette.fg_colors[i],
|
// palette.fg_colors[i],
|
||||||
));
|
// ));
|
||||||
|
|
||||||
x = if (i + 1) % 16 == 0 {
|
// x = if (i + 1) % 16 == 0 {
|
||||||
y += 24;
|
// y += 24;
|
||||||
initial_x
|
// initial_x
|
||||||
} else {
|
// } else {
|
||||||
x + PALETTE_RECT_WIDTH + 4
|
// x + PALETTE_RECT_WIDTH + 4
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
|
||||||
for bgc in &bg_colors {
|
// for bgc in &bg_colors {
|
||||||
bgc.draw(&mut canvas);
|
// bgc.draw(&mut canvas);
|
||||||
}
|
// }
|
||||||
for fgc in &fg_colors {
|
// for fgc in &fg_colors {
|
||||||
fgc.draw(&mut canvas);
|
// fgc.draw(&mut canvas);
|
||||||
}
|
// }
|
||||||
|
|
||||||
canvas.present();
|
// canvas.present();
|
||||||
|
|
||||||
let mut event_pump = sdl_context.event_pump().unwrap();
|
// let mut event_pump = sdl_context.event_pump().unwrap();
|
||||||
'running: loop {
|
// 'running: loop {
|
||||||
for event in event_pump.poll_iter() {
|
// for event in event_pump.poll_iter() {
|
||||||
match event {
|
// match event {
|
||||||
Event::Quit { .. } => break 'running,
|
// Event::Quit { .. } => break 'running,
|
||||||
Event::MouseButtonDown { x, y, .. } => {
|
// Event::MouseButtonDown { x, y, .. } => {
|
||||||
for bgc in &bg_colors {
|
// for bgc in &bg_colors {
|
||||||
if bgc.rect.contains_point(Point::new(x, y)) {
|
// if bgc.rect.contains_point(Point::new(x, y)) {
|
||||||
println!("BG Color #{}: {}", bgc.index, bgc.color);
|
// println!("BG Color #{}: {}", bgc.index, bgc.color);
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
for fgc in &fg_colors {
|
// for fgc in &fg_colors {
|
||||||
if fgc.rect.contains_point(Point::new(x, y)) {
|
// if fgc.rect.contains_point(Point::new(x, y)) {
|
||||||
println!("FG Color #{}: {}", fgc.index, fgc.color);
|
// println!("FG Color #{}: {}", fgc.index, fgc.color);
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
_ => {}
|
// _ => {}
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
|
Reference in a new issue