Fixed some sprites issues

This commit is contained in:
transistor 2021-10-31 23:01:56 -07:00
parent 8fe76334af
commit a3a11f7459

View File

@ -53,7 +53,10 @@ const MODE1_BF_HSYNC_INTERRUPT: u8 = 0x10;
const MODE2_BF_V_CELL_MODE: u8 = 0x08; const MODE2_BF_V_CELL_MODE: u8 = 0x08;
const MODE2_BF_VSYNC_INTERRUPT: u8 = 0x20; const MODE2_BF_VSYNC_INTERRUPT: u8 = 0x20;
const MODE3_BF_EXTERNAL_INTERRUPT: u8 = 0x08;
const MODE4_BF_H_CELL_MODE: u8 = 0x01; const MODE4_BF_H_CELL_MODE: u8 = 0x01;
const MODE4_BF_SHADOW_HIGHLIGHT: u8 = 0x08;
@ -188,6 +191,11 @@ impl Ym7101State {
(self.regs[REG_MODE_SET_2] & MODE2_BF_VSYNC_INTERRUPT) != 0 (self.regs[REG_MODE_SET_2] & MODE2_BF_VSYNC_INTERRUPT) != 0
} }
#[inline(always)]
fn external_int_enabled(&self) -> bool {
(self.regs[REG_MODE_SET_3] & MODE3_BF_EXTERNAL_INTERRUPT) != 0
}
pub fn get_vram_scroll_a_addr(&self) -> u32 { pub fn get_vram_scroll_a_addr(&self) -> u32 {
((self.regs[REG_SCROLL_A_ADDR] as u16) << 10) as u32 ((self.regs[REG_SCROLL_A_ADDR] as u16) << 10) as u32
} }
@ -282,24 +290,51 @@ impl Ym7101State {
} }
} }
pub fn draw_sprites(&mut self, frame: &mut Frame) { pub fn build_link_list(&mut self, sprite_table: usize, links: &mut [usize]) -> usize {
let sprite_table = (self.regs[REG_SPRITES_ADDR] as u32) << 9; links[0] = 0;
let (scroll_h, scroll_v) = self.get_scroll_size(); let mut i = 0;
loop {
let link = self.vram[sprite_table + (links[i] * 8) + 3];
if link == 0 || link > 80 {
break;
}
i += 1;
links[i] = link as usize;
}
i
}
pub fn draw_sprites(&mut self, frame: &mut Frame) {
let sprite_table = (self.regs[REG_SPRITES_ADDR] as usize) << 9;
let (cells_h, cells_v) = self.get_screen_size();
let (pos_limit_h, pos_limit_v) = (if cells_h == 32 { 383 } else { 447 }, if cells_v == 28 { 351 } else { 367 });
let mut links = [0; 80];
let lowest = self.build_link_list(sprite_table, &mut links);
for i in (0..lowest + 1).rev() {
let sprite_data = &self.vram[(sprite_table + (links[i] * 8))..];
for i in 0..(scroll_h as u32 * 2) {
let sprite_data = &self.vram[((sprite_table + (i * 8)) as usize)..];
let v_pos = read_beu16(&sprite_data[0..]); let v_pos = read_beu16(&sprite_data[0..]);
let size = sprite_data[2]; let size = sprite_data[2];
let link = sprite_data[3];
let pattern_name = read_beu16(&sprite_data[4..]); let pattern_name = read_beu16(&sprite_data[4..]);
let h_pos = read_beu16(&sprite_data[6..]); let h_pos = read_beu16(&sprite_data[6..]);
let (size_h, size_v) = (((size >> 2) & 0x03) as u16, (size & 0x03) as u16); let (size_h, size_v) = (((size >> 2) & 0x03) as u16 + 1, (size & 0x03) as u16 + 1);
let h_rev = (pattern_name & 0x0800) != 0;
let v_rev = (pattern_name & 0x1000) != 0;
println!("i: {} ({} {}) {:x} ({}, {}) {:x}", i, h_pos, v_pos, size, size_h, size_v, pattern_name);
for h in 0..size_h { for ih in 0..size_h {
for v in 0..size_v { for iv in 0..size_v {
let (h, v) = (if !h_rev { ih } else { size_h - ih }, if !v_rev { iv } else { size_v - iv });
let (x, y) = (h_pos + h * 8, v_pos + v * 8);
if x > 128 && x < pos_limit_h && y > 128 && y < pos_limit_v {
let iter = self.get_pattern_iter(pattern_name + (h * size_v) + v); let iter = self.get_pattern_iter(pattern_name + (h * size_v) + v);
frame.blit((h_pos + (h * 8)) as u32, (v_pos + (v * 8)) as u32, iter, 8, 8);
println!("{}: ({} {}), {:x}", i, x, y, pattern_name + (h * size_v) + v);
frame.blit(x as u32 - 128, y as u32 - 128, iter, 8, 8);
}
} }
} }
} }
@ -408,7 +443,7 @@ impl Steppable for Ym7101 {
let diff = (system.clock - self.state.last_clock) as u32; let diff = (system.clock - self.state.last_clock) as u32;
self.state.last_clock = system.clock; self.state.last_clock = system.clock;
if self.external_interrupt.get() { if self.state.external_int_enabled() && self.external_interrupt.get() {
self.external_interrupt.set(false); self.external_interrupt.set(false);
system.get_interrupt_controller().set(true, 2, 26)?; system.get_interrupt_controller().set(true, 2, 26)?;
} }
@ -549,7 +584,7 @@ impl Addressable for Ym7101 {
} }
} }
self.state.transfer_addr += self.state.regs[REG_AUTO_INCREMENT] as u32; self.state.transfer_addr += self.state.regs[REG_AUTO_INCREMENT] as u32;
info!("{}: data port read {} bytes from {:?}:{:x} returning {:x},{:x}", DEV_NAME, data.len(), self.state.transfer_target, addr, data[0], data[1]); debug!("{}: data port read {} bytes from {:?}:{:x} returning {:x},{:x}", DEV_NAME, data.len(), self.state.transfer_target, addr, data[0], data[1]);
}, },
// Read from Control Port // Read from Control Port
@ -573,7 +608,7 @@ impl Addressable for Ym7101 {
self.state.transfer_fill = if data.len() >= 2 { read_beu16(data) } else { data[0] as u16 }; self.state.transfer_fill = if data.len() >= 2 { read_beu16(data) } else { data[0] as u16 };
self.state.set_dma_mode(DmaType::Fill); self.state.set_dma_mode(DmaType::Fill);
} else { } else {
info!("{}: data port write {} bytes to {:?}:{:x} with {:?}", DEV_NAME, data.len(), self.state.transfer_target, self.state.transfer_addr, data); debug!("{}: data port write {} bytes to {:?}:{:x} with {:?}", DEV_NAME, data.len(), self.state.transfer_target, self.state.transfer_addr, data);
{ {
let addr = self.state.transfer_addr as usize; let addr = self.state.transfer_addr as usize;