mirror of
https://github.com/transistorfet/moa.git
synced 2024-11-18 14:05:57 +00:00
Fixed some sprites issues
This commit is contained in:
parent
8fe76334af
commit
a3a11f7459
@ -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;
|
||||||
|
Loading…
Reference in New Issue
Block a user