Add more audio regs; Add sprite struct

This commit is contained in:
Kevin Hamacher 2016-06-01 16:32:28 +02:00
parent 4221ed06ac
commit 8c0ef5529c
3 changed files with 87 additions and 11 deletions

View File

@ -34,6 +34,24 @@ const STAT_MODE_OAM_INT: u8 = 1 << 5;
const STAT_MODE_VBLANK_INT: u8 = 1 << 4;
const STAT_MODE_HBLANK_INT: u8 = 1 << 3;
// Sprite flags
/*
Bit7 OBJ-to-BG Priority (0=OBJ Above BG, 1=OBJ Behind BG color 1-3)
(Used for both BG and Window. BG color 0 is always behind OBJ)
Bit6 Y flip (0=Normal, 1=Vertically mirrored)
Bit5 X flip (0=Normal, 1=Horizontally mirrored)
Bit4 Palette number **Non CGB Mode Only** (0=OBP0, 1=OBP1)
Bit3 Tile VRAM-Bank **CGB Mode Only** (0=Bank 0, 1=Bank 1)
Bit2-0 Palette number **CGB Mode Only** (OBP0-7)
*/
const SPRITE_OBC_BG_PRIORITY: u8 = 1 << 7;
const SPRITE_Y_FLIP: u8 = 1 << 6;
const SPRITE_X_FLIP: u8 = 1 << 5;
const SPRITE_PALETTE_NO: u8 = 1 << 4; // NonCGB only
const SPRITE_TILE_VRAM_BANK: u8 = 1 << 3; // CGB only
#[derive(Debug)]
enum DisplayMode {
ReadOAMMemory,
@ -48,6 +66,13 @@ impl Default for DisplayMode {
}
}
struct Sprite {
x: u8,
y: u8,
tile: u8,
flags: u8,
}
pub struct Display {
control: u8,
status: u8,
@ -369,11 +394,37 @@ impl Display {
if self.control & CTRL_BG_SPRITE_SIZE > 0 {
println!("Wide sprites not tested!");
}
// Order sprites by priority
let mut queue: Vec<Sprite> = Vec::new();
for i in 0 .. 39 {
let mut y: u8 = self.oam[i * 4 + 0];
let mut x: u8 = self.oam[i * 4 + 1];
let t_num: u8 = self.oam[i * 4 + 2];
let flags: u8 = self.oam[i * 4 + 3];
queue.push(Sprite{
x: self.oam[i * 4 + 0],
y: self.oam[i * 4 + 1],
tile: self.oam[i * 4 + 2],
flags: self.oam[i * 4 + 3],
});
}
// This is the non-CGB priority.
// Smaller x coord = higher.
use std::cmp;
queue.sort_by(|x, y| {
if x.x > y.x {
cmp::Ordering::Greater
} else if x.x < y.x {
cmp::Ordering::Less
} else {
cmp::Ordering::Equal
}
});
queue.reverse();
for i in 0 .. 39 {
let mut y: u8 = queue[i].x;
let mut x: u8 = queue[i].y;
let t_num: u8 = queue[i].tile;
let flags: u8 = queue[i].flags;
if x == 0 || y == 0 {
// This sprite is hidden
@ -385,7 +436,11 @@ impl Display {
// Is this sprite on the current line?
if y.wrapping_add(8) >= render_y && y <= render_y {
let tile_offset_y: usize = render_y as usize - y as usize;
let y_o: u8 = match flags & SPRITE_Y_FLIP == SPRITE_Y_FLIP {
true => y ^ 7,
false => y
};
let tile_offset_y: usize = render_y as usize - y_o as usize;
let tile_base_addr: usize = 0 + t_num as usize * 16;
let tile_line_1 = self.vram[tile_base_addr + tile_offset_y * 2];
@ -403,12 +458,18 @@ impl Display {
let b1: bool;
let b2: bool;
let mut factor = 0;
let x_o2: u8 = match flags & SPRITE_X_FLIP == SPRITE_X_FLIP {
true => x_o ^ 7,
false => x_o,
};
if wide_mode && x_o > 7 {
b1 = (tile_line_3 & 1 << (14 - x_o)) > 0;
b2 = (tile_line_4 & 1 << (14 - x_o)) > 0;
b1 = (tile_line_3 & 1 << (14 - x_o2)) > 0;
b2 = (tile_line_4 & 1 << (14 - x_o2)) > 0;
} else {
b1 = (tile_line_1 & 1 << (7 - x_o)) > 0;
b2 = (tile_line_2 & 1 << (7 - x_o)) > 0;
b1 = (tile_line_1 & 1 << (7 - x_o2)) > 0;
b2 = (tile_line_2 & 1 << (7 - x_o2)) > 0;
}
if b1 {

View File

@ -42,7 +42,6 @@ impl MBC for MBC3 {
let addr = addr - 0xA000;
match self.active_ram_bank() {
0x00 ... 0x03 => {
println!("MBC3: Access RAM [{:02X}] {:04X}", self.ram_bank_no, addr);
self.ram[self.active_ram_bank() as usize * 0x2000 + addr as usize]
}
0x08 ... 0x0C => {
@ -89,7 +88,6 @@ impl MBC for MBC3 {
let addr = addr - 0xA000;
match self.active_ram_bank() {
0x00 ... 0x03 => {
println!("MBC3: Writing RAM [{:02X}] {:04X} = {:02X}", self.ram_bank_no, addr, val);
let active_bank = self.active_ram_bank() as usize;
self.ram[active_bank * 0x2000 + addr as usize] = val;
}

View File

@ -7,6 +7,11 @@ pub struct Sound {
sound_output_terminal_selector: u8,
sound_freq_low: u8,
sound_freq_high: u8,
channel2_sound_length: u8,
channel2_volume: u8,
channel2_freq_lo: u8,
channel2_freq_hi: u8,
}
impl Sound {
@ -20,6 +25,12 @@ impl Sound {
0xFF12 => self.sound_control_1 = val,
0xFF13 => self.sound_freq_low = val,
0xFF14 => self.sound_freq_high = val,
0xFF16 => self.channel2_sound_length = val,
0xFF17 => self.channel2_volume = val,
0xFF18 => self.channel2_freq_lo = val,
0xFF19 => self.channel2_freq_hi = val,
0xFF24 => self.sound_channel_volume_control = val,
0xFF25 => self.sound_output_terminal_selector = val,
0xFF26 => self.enabled = val,
@ -35,6 +46,12 @@ impl Sound {
0xFF12 => self.sound_control_1,
0xFF13 => self.sound_freq_low,
0xFF14 => self.sound_freq_high,
0xFF16 => self.channel2_sound_length,
0xFF17 => self.channel2_volume,
0xFF18 => self.channel2_freq_lo,
0xFF19 => self.channel2_freq_hi,
0xFF24 => self.sound_channel_volume_control,
0xFF25 => self.sound_output_terminal_selector,
0xFF26 => self.enabled,