diff options
Diffstat (limited to 'src/devices/video/ppu2c0x.cpp')
-rw-r--r-- | src/devices/video/ppu2c0x.cpp | 110 |
1 files changed, 69 insertions, 41 deletions
diff --git a/src/devices/video/ppu2c0x.cpp b/src/devices/video/ppu2c0x.cpp index dd895b469f1..39023752c8f 100644 --- a/src/devices/video/ppu2c0x.cpp +++ b/src/devices/video/ppu2c0x.cpp @@ -123,6 +123,8 @@ ppu2c0x_device::ppu2c0x_device(const machine_config& mconfig, device_type type, m_space_config("videoram", ENDIANNESS_LITTLE, 8, 17, 0, internal_map), m_cpu(*this, finder_base::DUMMY_TAG), m_scanline(0), // reset the scanline count + m_videoram_addr_mask(0x3fff), + m_global_refresh_mask(0x7fff), m_line_write_increment_large(32), m_paletteram_in_ppuspace(false), m_tile_page(0), @@ -803,6 +805,65 @@ void ppu2c0x_device::read_extra_sprite_bits(int sprite_index) // needed for some clones } +bool ppu2c0x_device::is_spritepixel_opaque(int pixel_data, int color) +{ + if (pixel_data) + return true; + else + return false; +} + +void ppu2c0x_device::draw_sprite_pixel_low(bitmap_rgb32& bitmap, int pixel_data, int pixel, int sprite_xpos, int color, int sprite_index, uint8_t* line_priority) +{ + if (is_spritepixel_opaque(pixel_data, color)) + { + /* has the background (or another sprite) already been drawn here? */ + if ((sprite_xpos + pixel) < VISIBLE_SCREEN_WIDTH) + { + if (!line_priority[sprite_xpos + pixel]) + { + /* no, draw */ + draw_sprite_pixel(sprite_xpos, color, pixel, pixel_data, bitmap); + } + /* indicate that a sprite was drawn at this location, even if it's not seen */ + line_priority[sprite_xpos + pixel] |= 0x01; + } + } + + /* set the "sprite 0 hit" flag if appropriate */ + if (sprite_index == 0 && (pixel_data & 0x03) && ((sprite_xpos + pixel) < 255) && (line_priority[sprite_xpos + pixel] & 0x02)) + m_regs[PPU_STATUS] |= PPU_STATUS_SPRITE0_HIT; +} + +void ppu2c0x_device::draw_sprite_pixel_high(bitmap_rgb32& bitmap, int pixel_data, int pixel, int sprite_xpos, int color, int sprite_index, uint8_t* line_priority) +{ + if (is_spritepixel_opaque(pixel_data, color)) + { + if ((sprite_xpos + pixel) < VISIBLE_SCREEN_WIDTH) + { + /* has another sprite been drawn here? */ + if (!(line_priority[sprite_xpos + pixel] & 0x01)) + { + /* no, draw */ + draw_sprite_pixel(sprite_xpos, color, pixel, pixel_data, bitmap); + line_priority[sprite_xpos + pixel] |= 0x01; + } + } + } + + /* set the "sprite 0 hit" flag if appropriate */ + if (sprite_index == 0 && (pixel_data & 0x03) && ((sprite_xpos + pixel) < 255) && (line_priority[sprite_xpos + pixel] & 0x02)) + m_regs[PPU_STATUS] |= PPU_STATUS_SPRITE0_HIT; +} + +int ppu2c0x_device::apply_sprite_pattern_page(int index1, int size) +{ + if (size == 8) + index1 += ((m_sprite_page == 0) ? 0 : 0x1000); + + return index1; +} + void ppu2c0x_device::draw_sprites(uint8_t* line_priority) { bitmap_rgb32& bitmap = *m_bitmap; @@ -881,8 +942,8 @@ void ppu2c0x_device::draw_sprites(uint8_t* line_priority) } index1 = tile * 16; - if (size == 8) - index1 += ((m_sprite_page == 0) ? 0 : 0x1000); + + index1 = apply_sprite_pattern_page(index1, size); read_sprite_plane_data(index1 + sprite_line); @@ -913,24 +974,7 @@ void ppu2c0x_device::draw_sprites(uint8_t* line_priority) /* is this pixel non-transparent? */ if (sprite_xpos + pixel >= first_pixel) { - if (pixel_data) - { - /* has the background (or another sprite) already been drawn here? */ - if ((sprite_xpos + pixel) < VISIBLE_SCREEN_WIDTH) - { - if (!line_priority[sprite_xpos + pixel]) - { - /* no, draw */ - draw_sprite_pixel(sprite_xpos, color, pixel, pixel_data, bitmap); - } - /* indicate that a sprite was drawn at this location, even if it's not seen */ - line_priority[sprite_xpos + pixel] |= 0x01; - } - } - - /* set the "sprite 0 hit" flag if appropriate */ - if (sprite_index == 0 && (pixel_data & 0x03) && ((sprite_xpos + pixel) < 255) && (line_priority[sprite_xpos + pixel] & 0x02)) - m_regs[PPU_STATUS] |= PPU_STATUS_SPRITE0_HIT; + draw_sprite_pixel_low(bitmap, pixel_data, pixel, sprite_xpos, color, sprite_index, line_priority); } } } @@ -945,23 +989,7 @@ void ppu2c0x_device::draw_sprites(uint8_t* line_priority) /* is this pixel non-transparent? */ if (sprite_xpos + pixel >= first_pixel) { - if (pixel_data) - { - if ((sprite_xpos + pixel) < VISIBLE_SCREEN_WIDTH) - { - /* has another sprite been drawn here? */ - if (!(line_priority[sprite_xpos + pixel] & 0x01)) - { - /* no, draw */ - draw_sprite_pixel(sprite_xpos, color, pixel, pixel_data, bitmap); - line_priority[sprite_xpos + pixel] |= 0x01; - } - } - } - - /* set the "sprite 0 hit" flag if appropriate */ - if (sprite_index == 0 && (pixel_data & 0x03) && ((sprite_xpos + pixel) < 255) && (line_priority[sprite_xpos + pixel] & 0x02)) - m_regs[PPU_STATUS] |= PPU_STATUS_SPRITE0_HIT; + draw_sprite_pixel_high(bitmap, pixel_data, pixel, sprite_xpos, color, sprite_index, line_priority); } } } @@ -1292,7 +1320,7 @@ void ppu2c0x_device::write(offs_t offset, uint8_t data) else { /* first write */ - m_refresh_latch &= 0x7fe0; + m_refresh_latch &= (0xffe0 & m_global_refresh_mask); m_refresh_latch |= (data & 0xf8) >> 3; m_x_fine = data & 7; @@ -1306,7 +1334,7 @@ void ppu2c0x_device::write(offs_t offset, uint8_t data) if (m_toggle) { /* second write */ - m_refresh_latch &= 0x7f00; + m_refresh_latch &= (0xff00 & m_global_refresh_mask); m_refresh_latch |= data; m_refresh_data = m_refresh_latch; @@ -1317,7 +1345,7 @@ void ppu2c0x_device::write(offs_t offset, uint8_t data) { /* first write */ m_refresh_latch &= 0x00ff; - m_refresh_latch |= (data & 0x3f) << 8; + m_refresh_latch |= (data & (m_videoram_addr_mask >>8) ) << 8; //logerror("vram addr write 1: %02x, %04x (scanline: %d)\n", data, m_refresh_latch, m_scanline); } @@ -1326,7 +1354,7 @@ void ppu2c0x_device::write(offs_t offset, uint8_t data) case PPU_DATA: /* 7 */ { - int tempAddr = m_videomem_addr & 0x3fff; + int tempAddr = m_videomem_addr & m_videoram_addr_mask; if (!m_latch.isnull()) m_latch(tempAddr); |