diff --git a/src/devices/video/ppu2c0x.cpp b/src/devices/video/ppu2c0x.cpp index 9ec7f66e2de..5da42b5cfcf 100644 --- a/src/devices/video/ppu2c0x.cpp +++ b/src/devices/video/ppu2c0x.cpp @@ -85,10 +85,11 @@ void ppu2c0x_device::device_config_complete() m_latch.set(nullptr); } -ppu2c0x_device::ppu2c0x_device(const machine_config& mconfig, device_type type, const char* tag, device_t* owner, uint32_t clock, address_map_constructor internal_map) : +ppu2c0x_device::ppu2c0x_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock, address_map_constructor internal_map) : device_t(mconfig, type, tag, owner, clock), device_memory_interface(mconfig, *this), device_video_interface(mconfig, *this), + device_palette_interface(mconfig, *this), 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 @@ -100,7 +101,7 @@ ppu2c0x_device::ppu2c0x_device(const machine_config& mconfig, device_type type, m_back_color(0), m_refresh_data(0), m_x_fine(0), - m_toggle(0), + m_toggle(false), m_tilecount(0), m_latch(*this), m_scanline_callback_proc(*this), @@ -116,7 +117,7 @@ ppu2c0x_device::ppu2c0x_device(const machine_config& mconfig, device_type type, m_scan_scale(1), // set the scan scale (this is for dual monitor vertical setups) m_draw_phase(0) { - for (auto& elem : m_regs) + for (auto &elem : m_regs) elem = 0; m_scanlines_per_frame = NTSC_SCANLINES_PER_FRAME; @@ -126,45 +127,45 @@ ppu2c0x_device::ppu2c0x_device(const machine_config& mconfig, device_type type, m_security_value = 0; } -ppu2c0x_device::ppu2c0x_device(const machine_config& mconfig, device_type type, const char* tag, device_t* owner, uint32_t clock) : +ppu2c0x_device::ppu2c0x_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock) : ppu2c0x_device(mconfig, type, tag, owner, clock, address_map_constructor(FUNC(ppu2c0x_device::ppu2c0x), this)) { m_paletteram_in_ppuspace = true; } -ppu2c0x_rgb_device::ppu2c0x_rgb_device(const machine_config& mconfig, device_type type, const char* tag, device_t* owner, uint32_t clock) : +ppu2c0x_rgb_device::ppu2c0x_rgb_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock) : ppu2c0x_device(mconfig, type, tag, owner, clock), m_palette_data(*this, "palette") { } // NTSC NES -ppu2c02_device::ppu2c02_device(const machine_config& mconfig, const char* tag, device_t* owner, uint32_t clock) : +ppu2c02_device::ppu2c02_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) : ppu2c0x_device(mconfig, PPU_2C02, tag, owner, clock) { } // Playchoice 10 -ppu2c03b_device::ppu2c03b_device(const machine_config& mconfig, const char* tag, device_t* owner, uint32_t clock) : +ppu2c03b_device::ppu2c03b_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) : ppu2c0x_rgb_device(mconfig, PPU_2C03B, tag, owner, clock) { } // Vs. Unisystem -ppu2c04_device::ppu2c04_device(const machine_config& mconfig, const char* tag, device_t* owner, uint32_t clock) : +ppu2c04_device::ppu2c04_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) : ppu2c0x_rgb_device(mconfig, PPU_2C04, tag, owner, clock) { } // PAL NES -ppu2c07_device::ppu2c07_device(const machine_config& mconfig, const char* tag, device_t* owner, uint32_t clock) : +ppu2c07_device::ppu2c07_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) : ppu2c0x_device(mconfig, PPU_2C07, tag, owner, clock) { m_scanlines_per_frame = PAL_SCANLINES_PER_FRAME; } // PAL clones -ppupalc_device::ppupalc_device(const machine_config& mconfig, const char* tag, device_t* owner, uint32_t clock) : +ppupalc_device::ppupalc_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) : ppu2c0x_device(mconfig, PPU_PALC, tag, owner, clock) { m_scanlines_per_frame = PAL_SCANLINES_PER_FRAME; @@ -173,32 +174,32 @@ ppupalc_device::ppupalc_device(const machine_config& mconfig, const char* tag, d // The PPU_2C05 variants have different protection value, set at device start, but otherwise are all the same... // Vs. Unisystem (Ninja Jajamaru Kun) -ppu2c05_01_device::ppu2c05_01_device(const machine_config& mconfig, const char* tag, device_t* owner, uint32_t clock) : +ppu2c05_01_device::ppu2c05_01_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) : ppu2c0x_rgb_device(mconfig, PPU_2C05_01, tag, owner, clock) { m_security_value = 0x1b; // game (jajamaru) doesn't seem to ever actually check it } // Vs. Unisystem (Mighty Bomb Jack) -ppu2c05_02_device::ppu2c05_02_device(const machine_config& mconfig, const char* tag, device_t* owner, uint32_t clock) : +ppu2c05_02_device::ppu2c05_02_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) : ppu2c0x_rgb_device(mconfig, PPU_2C05_02, tag, owner, clock) { m_security_value = 0x3d; } // Vs. Unisystem (Gumshoe) -ppu2c05_03_device::ppu2c05_03_device(const machine_config& mconfig, const char* tag, device_t* owner, uint32_t clock) : +ppu2c05_03_device::ppu2c05_03_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) : ppu2c0x_rgb_device(mconfig, PPU_2C05_03, tag, owner, clock) { m_security_value = 0x1c; } // Vs. Unisystem (Top Gun) -ppu2c05_04_device::ppu2c05_04_device(const machine_config& mconfig, const char* tag, device_t* owner, uint32_t clock) : +ppu2c05_04_device::ppu2c05_04_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) : ppu2c0x_rgb_device(mconfig, PPU_2C05_04, tag, owner, clock) { m_security_value = 0x1b; } // Vs. Unisystem (Super Mario Bros. bootlegs) -ppu2c04_clone_device::ppu2c04_clone_device(const machine_config& mconfig, const char* tag, device_t* owner, uint32_t clock) : +ppu2c04_clone_device::ppu2c04_clone_device(const machine_config &mconfig, const char *tag, device_t* owner, u32 clock) : ppu2c0x_device(mconfig, PPU_2C04C, tag, owner, clock), m_palette_data(*this, "palette") { @@ -206,7 +207,7 @@ ppu2c04_clone_device::ppu2c04_clone_device(const machine_config& mconfig, const m_vblank_first_scanline = VBLANK_FIRST_SCANLINE_VS_CLONE; // background and sprites are always enabled; monochrome and color emphasis aren't supported - m_regs[PPU_CONTROL1] = ~(PPU_CONTROL1_COLOR_EMPHASIS | PPU_CONTROL1_DISPLAY_MONO); + m_regs[PPU_CONTROL1] = u8(~(PPU_CONTROL1_COLOR_EMPHASIS | PPU_CONTROL1_DISPLAY_MONO)); } //------------------------------------------------- @@ -226,8 +227,8 @@ void ppu2c0x_device::start_nopalram() m_nmi_timer->adjust(attotime::never); /* allocate a screen bitmap, videomem and spriteram, a dirtychar array and the monochromatic colortable */ - m_bitmap = std::make_unique(VISIBLE_SCREEN_WIDTH, VISIBLE_SCREEN_HEIGHT); - m_spriteram = make_unique_clear(SPRITERAM_SIZE); + m_bitmap.allocate(VISIBLE_SCREEN_WIDTH, VISIBLE_SCREEN_HEIGHT); + m_spriteram = make_unique_clear(SPRITERAM_SIZE); init_palette_tables(); @@ -252,7 +253,7 @@ void ppu2c0x_device::start_nopalram() save_item(NAME(m_tilecount)); save_pointer(NAME(m_spriteram), SPRITERAM_SIZE); - save_item(NAME(*m_bitmap)); + save_item(NAME(m_bitmap)); } void ppu2c0x_device::device_start() @@ -280,7 +281,7 @@ void ppu2c04_clone_device::device_start() also generally affects PPU-side read timings involving the OAM, but this still doesn't seem to matter for Vs. SMB specifically) */ - m_spritebuf = make_unique_clear(SPRITERAM_SIZE); + m_spritebuf = make_unique_clear(SPRITERAM_SIZE); save_pointer(NAME(m_spritebuf), SPRITERAM_SIZE); } @@ -292,7 +293,7 @@ void ppu2c04_clone_device::device_start() // readbyte - read a byte at the given address //------------------------------------------------- -uint8_t ppu2c0x_device::readbyte(offs_t address) +u8 ppu2c0x_device::readbyte(offs_t address) { return space().read_byte(address); } @@ -302,15 +303,15 @@ uint8_t ppu2c0x_device::readbyte(offs_t address) // writebyte - write a byte at the given address //------------------------------------------------- -inline void ppu2c0x_device::writebyte(offs_t address, uint8_t data) +inline void ppu2c0x_device::writebyte(offs_t address, u8 data) { space().write_byte(address, data); } -inline uint16_t ppu2c0x_device::apply_grayscale_and_emphasis(uint8_t color) +inline u16 ppu2c0x_device::apply_grayscale_and_emphasis(u8 color) { - uint16_t palval = color; + u16 palval = color; palval &= (m_regs[PPU_CONTROL1] & PPU_CONTROL1_DISPLAY_MONO) ? 0x30 : 0x3f; palval |= (m_regs[PPU_CONTROL1] & PPU_CONTROL1_COLOR_EMPHASIS) << 1; @@ -413,7 +414,7 @@ rgb_t ppu2c0x_device::nespal_to_RGB(int color_intensity, int color_num, int colo void ppu2c0x_device::init_palette_tables() { - bool is_pal = m_scanlines_per_frame != NTSC_SCANLINES_PER_FRAME; + const bool is_pal = m_scanlines_per_frame != NTSC_SCANLINES_PER_FRAME; /* This routine builds a palette using a transformation from */ /* the YUV (Y, B-Y, R-Y) to the RGB color space */ @@ -433,9 +434,9 @@ void ppu2c0x_device::init_palette_tables() /* loop through the 16 colors */ for (int color_num = 0; color_num < 16; color_num++) { - rgb_t col = nespal_to_RGB(color_intensity, color_num, color_emphasis, is_pal); + const rgb_t col = nespal_to_RGB(color_intensity, color_num, color_emphasis, is_pal); - m_nespens[entry] = (uint32_t)col; + set_pen_color(entry, col); entry++; } @@ -451,11 +452,11 @@ void ppu2c0x_rgb_device::init_palette_tables() { for (int color_num = 0; color_num < 64; color_num++) { - int R = ((color_emphasis & 1) ? 7 : m_palette_data[color_num * 3]); - int G = ((color_emphasis & 2) ? 7 : m_palette_data[color_num * 3 + 1]); - int B = ((color_emphasis & 4) ? 7 : m_palette_data[color_num * 3 + 2]); + const int R = ((color_emphasis & 1) ? 7 : m_palette_data[color_num * 3]); + const int G = ((color_emphasis & 2) ? 7 : m_palette_data[color_num * 3 + 1]); + const int B = ((color_emphasis & 4) ? 7 : m_palette_data[color_num * 3 + 2]); - m_nespens[entry] = (pal3bit(R)<<16) | (pal3bit(G)<<8) | pal3bit(B); + set_pen_color(entry, rgb_t(pal3bit(R), pal3bit(G), pal3bit(B))); //set_pen_color(entry++, pal3bit(R), pal3bit(G), pal3bit(B)); entry++; @@ -472,12 +473,12 @@ void ppu2c04_clone_device::init_palette_tables() for (int color_num = 0; color_num < 64*2; color_num++) { /* A7 line on palette ROMs is always high, color bits are in reverse order */ - u8 color = m_palette_data[color_num | 0x80]; - int R = bitswap<3>(color, 0, 1, 2); - int G = bitswap<3>(color, 3, 4, 5); - int B = bitswap<2>(color, 6, 7); + const u8 color = m_palette_data[color_num | 0x80]; + const int R = bitswap<3>(color, 0, 1, 2); + const int G = bitswap<3>(color, 3, 4, 5); + const int B = bitswap<2>(color, 6, 7); - m_nespens[color_num] = (pal3bit(R) << 16) | (pal3bit(G) << 8) | pal2bit(B); + set_pen_color(color_num, rgb_t(pal3bit(R), pal3bit(G), pal2bit(B))); } } @@ -493,8 +494,8 @@ void ppu2c04_clone_device::init_palette_tables() TIMER_CALLBACK_MEMBER(ppu2c0x_device::hblank_tick) { - bool blanked = (m_regs[PPU_CONTROL1] & (PPU_CONTROL1_BACKGROUND | PPU_CONTROL1_SPRITES)) == 0; - bool vblank = (m_scanline >= m_vblank_first_scanline - 1) && (m_scanline < m_scanlines_per_frame - 1); + const bool blanked = (m_regs[PPU_CONTROL1] & (PPU_CONTROL1_BACKGROUND | PPU_CONTROL1_SPRITES)) == 0; + const bool vblank = (m_scanline >= m_vblank_first_scanline - 1) && (m_scanline < m_scanlines_per_frame - 1); //update_scanline(); @@ -515,8 +516,8 @@ TIMER_CALLBACK_MEMBER(ppu2c0x_device::nmi_tick) TIMER_CALLBACK_MEMBER(ppu2c0x_device::scanline_tick) { - bool blanked = (m_regs[PPU_CONTROL1] & (PPU_CONTROL1_BACKGROUND | PPU_CONTROL1_SPRITES)) == 0; - bool vblank = ((m_scanline >= m_vblank_first_scanline - 1) && (m_scanline < m_scanlines_per_frame - 1)) ? 1 : 0; + const bool blanked = (m_regs[PPU_CONTROL1] & (PPU_CONTROL1_BACKGROUND | PPU_CONTROL1_SPRITES)) == 0; + const bool vblank = ((m_scanline >= m_vblank_first_scanline - 1) && (m_scanline < m_scanlines_per_frame - 1)) ? 1 : 0; /* if a callback is available, call it */ if (!m_scanline_callback_proc.isnull()) @@ -585,30 +586,30 @@ void ppu2c0x_device::read_tile_plane_data(int address, int color) m_planebuf[1] = readbyte((address + 8) & 0x1fff); } -void ppu2c0x_device::shift_tile_plane_data(uint8_t& pix) +void ppu2c0x_device::shift_tile_plane_data(u8& pix) { pix = BIT(m_planebuf[0], 7) | (BIT(m_planebuf[1], 7) << 1); m_planebuf[0] <<= 1; m_planebuf[1] <<= 1; } -void ppu2c0x_device::draw_tile_pixel(uint8_t pix, int color, uint32_t back_pen, uint32_t*& dest) +void ppu2c0x_device::draw_tile_pixel(u8 pix, int color, u32 back_pen, u32*& dest) { - uint16_t palval = pix ? m_palette_ram[((4 * color) + pix) & 0x1f] : back_pen; + const u16 palval = pix ? m_palette_ram[((4 * color) + pix) & 0x1f] : back_pen; - *dest = m_nespens[apply_grayscale_and_emphasis(palval)]; + *dest = pen_color(apply_grayscale_and_emphasis(palval)); } -void ppu2c0x_device::draw_tile(uint8_t* line_priority, int color_byte, int color_bits, int address, int start_x, uint32_t back_pen, uint32_t*& dest) +void ppu2c0x_device::draw_tile(u8* line_priority, int color_byte, int color_bits, int address, int start_x, u32 back_pen, u32*& dest) { - int color = (color_byte >> color_bits) & 0x03; + const int color = (color_byte >> color_bits) & 0x03; read_tile_plane_data(address, color); /* render the pixel */ for (int i = 0; i < 8; i++) { - uint8_t pix; + u8 pix; shift_tile_plane_data(pix); if ((start_x + i) >= 0 && (start_x + i) < VISIBLE_SCREEN_WIDTH) @@ -628,16 +629,14 @@ void ppu2c0x_device::draw_tile(uint8_t* line_priority, int color_byte, int color // making raster effects more complex than on other systems // https://retrocomputing.stackexchange.com/questions/1898/how-can-i-create-a-split-scroll-effect-in-an-nes-game -void ppu2c0x_device::draw_background(uint8_t* line_priority) +void ppu2c0x_device::draw_background(u8* line_priority) { - bitmap_rgb32& bitmap = *m_bitmap; - /* determine where in the nametable to start drawing from */ /* based on the current scanline and scroll regs */ - uint8_t scroll_x_coarse = m_refresh_data & 0x001f; - uint8_t scroll_y_coarse = (m_refresh_data & 0x03e0) >> 5; - uint16_t nametable = m_refresh_data & 0x0c00; - uint8_t scroll_y_fine = (m_refresh_data & 0x7000) >> 12; + const u8 scroll_x_coarse = m_refresh_data & 0x001f; + const u8 scroll_y_coarse = (m_refresh_data & 0x03e0) >> 5; + const u16 nametable = m_refresh_data & 0x0c00; + const u8 scroll_y_fine = (m_refresh_data & 0x7000) >> 12; int x = scroll_x_coarse; @@ -646,33 +645,27 @@ void ppu2c0x_device::draw_background(uint8_t* line_priority) /* set up dest */ int start_x = (m_x_fine ^ 0x07) - 7; - uint32_t* dest = &bitmap.pix(m_scanline, start_x); + u32* dest = &m_bitmap.pix(m_scanline, start_x); m_tilecount = 0; /* draw the 32 or 33 tiles that make up a line */ while (m_tilecount < 34) { - int color_byte; - int color_bits; - int pos; - int index1; - int page, page2, address; - - index1 = tile_index + x; + const int index1 = tile_index + x; // page2 is the output of the nametable read (this section is the FIRST read per tile!) - page2 = readbyte(index1); + const int page2 = readbyte(index1); // this is attribute table stuff! (actually read 2 in PPUspeak)! /* Figure out which byte in the color table to use */ - pos = ((index1 & 0x380) >> 4) | ((index1 & 0x1f) >> 2); - page = (index1 & 0x0c00) >> 10; - address = 0x3c0 + pos; - color_byte = readbyte((((page * 0x400) + address) & 0xfff) + 0x2000); + const int pos = ((index1 & 0x380) >> 4) | ((index1 & 0x1f) >> 2); + const int page = (index1 & 0x0c00) >> 10; + int address = 0x3c0 + pos; + const int color_byte = readbyte((((page * 0x400) + address) & 0xfff) + 0x2000); /* figure out which bits in the color table to use */ - color_bits = ((index1 & 0x40) >> 4) + (index1 & 0x02); + const int color_bits = ((index1 & 0x40) >> 4) + (index1 & 0x02); // 27/12/2002 if (!m_latch.isnull()) @@ -681,7 +674,7 @@ void ppu2c0x_device::draw_background(uint8_t* line_priority) if (start_x < VISIBLE_SCREEN_WIDTH) { // need to read 0x0000 or 0x1000 + 16*nametable data - address = ((m_tile_page) ? 0x1000 : 0) + (page2 * 16); + address = (m_tile_page ? 0x1000 : 0) + (page2 * 16); // plus something that accounts for y address += scroll_y_fine; @@ -703,7 +696,7 @@ void ppu2c0x_device::draw_background(uint8_t* line_priority) /* if the left 8 pixels for the background are off, blank 'em */ if (!(m_regs[PPU_CONTROL1] & PPU_CONTROL1_BACKGROUND_L8)) { - dest = &bitmap.pix(m_scanline); + dest = &m_bitmap.pix(m_scanline); for (int i = 0; i < 8; i++) { draw_back_pen(dest, m_back_color); @@ -714,7 +707,7 @@ void ppu2c0x_device::draw_background(uint8_t* line_priority) } } -void ppu2c04_clone_device::draw_background(uint8_t* line_priority) +void ppu2c04_clone_device::draw_background(u8* line_priority) { // nametable selection is ignored below the hardwired scroll split position if (m_scanline < 31) @@ -723,18 +716,16 @@ void ppu2c04_clone_device::draw_background(uint8_t* line_priority) ppu2c0x_device::draw_background(line_priority); } -void ppu2c0x_device::draw_back_pen(uint32_t* dest, int back_pen) +void ppu2c0x_device::draw_back_pen(u32* dest, int back_pen) { - *dest = m_nespens[apply_grayscale_and_emphasis(back_pen)]; + *dest = pen_color(apply_grayscale_and_emphasis(back_pen)); } void ppu2c0x_device::draw_background_pen() { - bitmap_rgb32& bitmap = *m_bitmap; - // Fill this scanline with the background pen. - for (int i = 0; i < bitmap.width(); i++) - draw_back_pen(&bitmap.pix(m_scanline, i), m_back_color); + for (int i = 0; i < m_bitmap.width(); i++) + draw_back_pen(&m_bitmap.pix(m_scanline, i), m_back_color); } void ppu2c0x_device::read_sprite_plane_data(int address) @@ -743,7 +734,7 @@ void ppu2c0x_device::read_sprite_plane_data(int address) m_planebuf[1] = readbyte((address + 8) & 0x1fff); } -void ppu2c0x_device::make_sprite_pixel_data(uint8_t& pixel_data, int flipx) +void ppu2c0x_device::make_sprite_pixel_data(u8 &pixel_data, bool flipx) { if (flipx) { @@ -759,23 +750,20 @@ void ppu2c0x_device::make_sprite_pixel_data(uint8_t& pixel_data, int flipx) } } -void ppu2c0x_device::draw_sprite_pixel(int sprite_xpos, int color, int pixel, uint8_t pixel_data, bitmap_rgb32& bitmap) +void ppu2c0x_device::draw_sprite_pixel(int sprite_xpos, int color, int pixel, u8 pixel_data, bitmap_rgb32 &bitmap) { - uint16_t palval = m_palette_ram[((4 * color) | pixel_data) & 0x1f]; - uint32_t pix = m_nespens[apply_grayscale_and_emphasis(palval)]; - - bitmap.pix(m_scanline, sprite_xpos + pixel) = pix; + const u16 palval = m_palette_ram[((4 * color) | pixel_data) & 0x1f]; + bitmap.pix(m_scanline, sprite_xpos + pixel) = pen_color(apply_grayscale_and_emphasis(palval)); } -void ppu2c04_clone_device::draw_sprite_pixel(int sprite_xpos, int color, int pixel, uint8_t pixel_data, bitmap_rgb32 &bitmap) +void ppu2c04_clone_device::draw_sprite_pixel(int sprite_xpos, int color, int pixel, u8 pixel_data, bitmap_rgb32 &bitmap) { /* clone PPU clips sprites at the screen edges */ if ((sprite_xpos + pixel < 8) || (sprite_xpos + pixel) >= (VISIBLE_SCREEN_WIDTH - 6)) return; - uint16_t palval = m_palette_ram[((4 * color) | pixel_data) & 0x1f]; - uint32_t pix = m_nespens[palval | 0x40]; - bitmap.pix(m_scanline, sprite_xpos + pixel) = pix; + const u16 palval = m_palette_ram[((4 * color) | pixel_data) & 0x1f]; + bitmap.pix(m_scanline, sprite_xpos + pixel) = pen_color(palval | 0x40); } void ppu2c0x_device::read_extra_sprite_bits(int sprite_index) @@ -791,7 +779,7 @@ bool ppu2c0x_device::is_spritepixel_opaque(int pixel_data, int color) 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) +void ppu2c0x_device::draw_sprite_pixel_low(bitmap_rgb32 &bitmap, int pixel_data, int pixel, int sprite_xpos, int color, int sprite_index, u8 *line_priority) { if (is_spritepixel_opaque(pixel_data, color)) { @@ -813,14 +801,14 @@ void ppu2c0x_device::draw_sprite_pixel_low(bitmap_rgb32& bitmap, int pixel_data, 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) +void ppu2c0x_device::draw_sprite_pixel_high(bitmap_rgb32 &bitmap, int pixel_data, int pixel, int sprite_xpos, int color, int sprite_index, u8 *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)) + if (BIT(~line_priority[sprite_xpos + pixel], 0)) { /* no, draw */ draw_sprite_pixel(sprite_xpos, color, pixel, pixel_data, bitmap); @@ -842,31 +830,19 @@ int ppu2c0x_device::apply_sprite_pattern_page(int index1, int size) return index1; } -void ppu2c0x_device::draw_sprites(uint8_t* line_priority) +void ppu2c0x_device::draw_sprites(u8 *line_priority) { - bitmap_rgb32& bitmap = *m_bitmap; - - int sprite_xpos, sprite_ypos, sprite_index; - int tile, index1; - int pri; - - int flipx, flipy, color; - int size; int sprite_count = 0; - int sprite_line; - - int first_pixel; - int pixel; /* determine if the sprites are 8x8 or 8x16 */ - size = (m_regs[PPU_CONTROL0] & PPU_CONTROL0_SPRITE_SIZE) ? 16 : 8; + int size = (m_regs[PPU_CONTROL0] & PPU_CONTROL0_SPRITE_SIZE) ? 16 : 8; - first_pixel = (m_regs[PPU_CONTROL1] & PPU_CONTROL1_SPRITES_L8) ? 0 : 8; + int first_pixel = (m_regs[PPU_CONTROL1] & PPU_CONTROL1_SPRITES_L8) ? 0 : 8; - for (sprite_index = 0; sprite_index < SPRITERAM_SIZE; sprite_index += 4) + for (int sprite_index = 0; sprite_index < SPRITERAM_SIZE; sprite_index += 4) { - sprite_ypos = m_spriteram[sprite_index] + 1; - sprite_xpos = m_spriteram[sprite_index + 3]; + int sprite_ypos = m_spriteram[sprite_index] + 1; + int sprite_xpos = m_spriteram[sprite_index + 3]; // The sprite collision acts funny on the last pixel of a scanline. // The various scanline latches update while the last few pixels @@ -887,17 +863,17 @@ void ppu2c0x_device::draw_sprites(uint8_t* line_priority) if ((sprite_ypos + size <= m_scanline) || (sprite_ypos > m_scanline)) continue; - tile = m_spriteram[sprite_index + 1]; - color = (m_spriteram[sprite_index + 2] & 0x03) + 4; - pri = m_spriteram[sprite_index + 2] & 0x20; - flipx = m_spriteram[sprite_index + 2] & 0x40; - flipy = m_spriteram[sprite_index + 2] & 0x80; + int tile = m_spriteram[sprite_index + 1]; + const int color = (m_spriteram[sprite_index + 2] & 0x03) + 4; + const bool pri = BIT(m_spriteram[sprite_index + 2], 5); + const bool flipx = BIT(m_spriteram[sprite_index + 2], 6); + const bool flipy = BIT(m_spriteram[sprite_index + 2], 7); read_extra_sprite_bits(sprite_index); if (size == 16) { /* if it's 8x16 and odd-numbered, draw the other half instead */ - if (tile & 0x01) + if (BIT(tile, 0)) { tile &= ~0x01; tile |= 0x100; @@ -908,7 +884,7 @@ void ppu2c0x_device::draw_sprites(uint8_t* line_priority) m_latch((m_sprite_page << 10) | ((tile & 0xff) << 4)); /* compute the character's line to draw */ - sprite_line = m_scanline - sprite_ypos; + int sprite_line = m_scanline - sprite_ypos; if (flipy) sprite_line = (size - 1) - sprite_line; @@ -919,7 +895,7 @@ void ppu2c0x_device::draw_sprites(uint8_t* line_priority) sprite_line -= 8; } - index1 = tile * 16; + int index1 = tile * 16; index1 = apply_sprite_pattern_page(index1, size); @@ -944,37 +920,37 @@ void ppu2c0x_device::draw_sprites(uint8_t* line_priority) if (pri) { /* draw the low-priority sprites */ - for (pixel = 0; pixel < 8; pixel++) + for (int pixel = 0; pixel < 8; pixel++) { - uint8_t pixel_data; + u8 pixel_data; make_sprite_pixel_data(pixel_data, flipx); /* is this pixel non-transparent? */ if (sprite_xpos + pixel >= first_pixel) { - draw_sprite_pixel_low(bitmap, pixel_data, pixel, sprite_xpos, color, sprite_index, line_priority); + draw_sprite_pixel_low(m_bitmap, pixel_data, pixel, sprite_xpos, color, sprite_index, line_priority); } } } else { /* draw the high-priority sprites */ - for (pixel = 0; pixel < 8; pixel++) + for (int pixel = 0; pixel < 8; pixel++) { - uint8_t pixel_data; + u8 pixel_data; make_sprite_pixel_data(pixel_data, flipx); /* is this pixel non-transparent? */ if (sprite_xpos + pixel >= first_pixel) { - draw_sprite_pixel_high(bitmap, pixel_data, pixel, sprite_xpos, color, sprite_index, line_priority); + draw_sprite_pixel_high(m_bitmap, pixel_data, pixel, sprite_xpos, color, sprite_index, line_priority); } } } } } -void ppu2c04_clone_device::draw_sprites(uint8_t *line_priority) +void ppu2c04_clone_device::draw_sprites(u8 *line_priority) { ppu2c0x_device::draw_sprites(line_priority); @@ -995,7 +971,7 @@ void ppu2c04_clone_device::draw_sprites(uint8_t *line_priority) void ppu2c0x_device::render_scanline() { - uint8_t line_priority[VISIBLE_SCREEN_WIDTH]; + u8 line_priority[VISIBLE_SCREEN_WIDTH]; // lets see how long it takes auto profile = g_profiler.start(PROFILER_USER1); @@ -1027,8 +1003,7 @@ void ppu2c0x_device::scanline_increment_fine_ycounter() /* if it's rolled, increment the coarse y-scroll */ if (m_refresh_data & 0x8000) { - uint16_t tmp; - tmp = (m_refresh_data & 0x03e0) + 0x20; + const u16 tmp = (m_refresh_data & 0x03e0) + 0x20; m_refresh_data &= 0x7c1f; /* handle bizarro scrolling rollover at the 30th (not 32nd) vertical tile */ @@ -1057,8 +1032,7 @@ void ppu2c0x_device::update_visible_enabled_scanline() void ppu2c0x_device::update_visible_disabled_scanline() { - bitmap_rgb32& bitmap = *m_bitmap; - uint32_t back_pen = m_back_color; + u32 back_pen = m_back_color; if (m_paletteram_in_ppuspace) { @@ -1075,8 +1049,8 @@ void ppu2c0x_device::update_visible_disabled_scanline() } // Fill this scanline with the background pen. - for (int i = 0; i < bitmap.width(); i++) - draw_back_pen(&bitmap.pix(m_scanline, i), back_pen); + for (int i = 0; i < m_bitmap.width(); i++) + draw_back_pen(&m_bitmap.pix(m_scanline, i), back_pen); } void ppu2c0x_device::update_visible_scanline() @@ -1111,7 +1085,7 @@ void ppu2c0x_device::update_scanline() * *************************************/ -void ppu2c0x_device::palette_write(offs_t offset, uint8_t data) +void ppu2c0x_device::palette_write(offs_t offset, u8 data) { // palette RAM is only 6 bits wide data &= 0x3f; @@ -1132,7 +1106,7 @@ void ppu2c0x_device::palette_write(offs_t offset, uint8_t data) } } -uint8_t ppu2c0x_device::palette_read(offs_t offset) +u8 ppu2c0x_device::palette_read(offs_t offset) { if (m_regs[PPU_CONTROL1] & PPU_CONTROL1_DISPLAY_MONO) return m_palette_ram[offset & 0x1f] & 0x30; @@ -1146,7 +1120,7 @@ uint8_t ppu2c0x_device::palette_read(offs_t offset) * *************************************/ -uint8_t ppu2c0x_device::read(offs_t offset) +u8 ppu2c0x_device::read(offs_t offset) { if (offset >= PPU_MAX_REG) { @@ -1166,7 +1140,7 @@ uint8_t ppu2c0x_device::read(offs_t offset) m_data_latch = m_regs[PPU_STATUS] | (m_data_latch & 0x1f); // Reset hi/lo scroll toggle - m_toggle = 0; + m_toggle = false; // If the vblank bit is set, clear all status bits but the 2 sprite flags if (m_data_latch & PPU_STATUS_VBLANK) @@ -1203,7 +1177,7 @@ uint8_t ppu2c0x_device::read(offs_t offset) return m_data_latch; } -uint8_t ppu2c04_clone_device::read(offs_t offset) +u8 ppu2c04_clone_device::read(offs_t offset) { switch (offset & 7) { @@ -1227,7 +1201,7 @@ uint8_t ppu2c04_clone_device::read(offs_t offset) * *************************************/ -void ppu2c0x_device::write(offs_t offset, uint8_t data) +void ppu2c0x_device::write(offs_t offset, u8 data) { if (offset >= PPU_MAX_REG) { @@ -1301,7 +1275,7 @@ void ppu2c0x_device::write(offs_t offset, uint8_t data) //logerror("scroll write 1: %d, %04x (scanline: %d)\n", data, m_refresh_latch, m_scanline); } - m_toggle ^= 1; + m_toggle = !m_toggle; break; case PPU_ADDRESS: /* 6 */ @@ -1323,12 +1297,12 @@ void ppu2c0x_device::write(offs_t offset, uint8_t data) //logerror("vram addr write 1: %02x, %04x (scanline: %d)\n", data, m_refresh_latch, m_scanline); } - m_toggle ^= 1; + m_toggle = !m_toggle; break; case PPU_DATA: /* 7 */ { - int tempAddr = m_videomem_addr & m_videoram_addr_mask; + const int tempAddr = m_videomem_addr & m_videoram_addr_mask; if (!m_latch.isnull()) m_latch(tempAddr); @@ -1360,7 +1334,7 @@ void ppu2c0x_device::write(offs_t offset, uint8_t data) m_data_latch = data; } -void ppu2c04_clone_device::write(offs_t offset, uint8_t data) +void ppu2c04_clone_device::write(offs_t offset, u8 data) { switch (offset & 7) { @@ -1396,19 +1370,19 @@ void ppu2c04_clone_device::write(offs_t offset, uint8_t data) set_vram_dest((get_vram_dest() & 0x00ff) | (data << 8)); } - m_toggle ^= 1; + m_toggle = !m_toggle; return; } ppu2c0x_device::write(offset, data); } -uint16_t ppu2c0x_device::get_vram_dest() +u16 ppu2c0x_device::get_vram_dest() { return m_videomem_addr; } -void ppu2c0x_device::set_vram_dest(uint16_t dest) +void ppu2c0x_device::set_vram_dest(u16 dest) { m_videomem_addr = dest; } @@ -1419,13 +1393,13 @@ void ppu2c0x_device::set_vram_dest(uint16_t dest) * *************************************/ -void ppu2c0x_device::spriteram_dma(address_space& space, const uint8_t page) +void ppu2c0x_device::spriteram_dma(address_space& space, const u8 page) { - int address = page << 8; + const int address = page << 8; for (int i = 0; i < SPRITERAM_SIZE; i++) { - uint8_t spriteData = space.read_byte(address + i); + const u8 spriteData = space.read_byte(address + i); space.write_byte(0x2004, spriteData); } @@ -1439,17 +1413,17 @@ void ppu2c0x_device::spriteram_dma(address_space& space, const uint8_t page) * *************************************/ -void ppu2c0x_device::render(bitmap_rgb32& bitmap, int flipx, int flipy, int sx, int sy, const rectangle& cliprect) +void ppu2c0x_device::render(bitmap_rgb32& bitmap, bool flipx, bool flipy, int sx, int sy, const rectangle& cliprect) { if (m_scanline_timer->remaining() != attotime::zero) { // Partial line update, need to render first (especially for light gun emulation). update_scanline(); } - copybitmap(bitmap, *m_bitmap, flipx, flipy, sx, sy, cliprect); + copybitmap(bitmap, m_bitmap, flipx, flipy, sx, sy, cliprect); } -uint32_t ppu2c0x_device::screen_update(screen_device& screen, bitmap_rgb32& bitmap, const rectangle& cliprect) +u32 ppu2c0x_device::screen_update(screen_device& screen, bitmap_rgb32& bitmap, const rectangle& cliprect) { render(bitmap, 0, 0, 0, 0, cliprect); return 0; diff --git a/src/devices/video/ppu2c0x.h b/src/devices/video/ppu2c0x.h index 980a81ce231..01ca1f3bc93 100644 --- a/src/devices/video/ppu2c0x.h +++ b/src/devices/video/ppu2c0x.h @@ -42,7 +42,8 @@ class ppu2c0x_device : public device_t, public device_memory_interface, - public device_video_interface + public device_video_interface, + public device_palette_interface { public: typedef device_delegate scanline_delegate; @@ -69,47 +70,17 @@ public: // are non-rendering and non-vblank. }; - virtual uint8_t read(offs_t offset); - virtual void write(offs_t offset, uint8_t data); - virtual uint8_t palette_read(offs_t offset); - virtual void palette_write(offs_t offset, uint8_t data); + virtual u8 read(offs_t offset); + virtual void write(offs_t offset, u8 data); + virtual u8 palette_read(offs_t offset); + virtual void palette_write(offs_t offset, u8 data); template void set_cpu_tag(T &&tag) { m_cpu.set_tag(std::forward(tag)); } auto int_callback() { return m_int_callback.bind(); } - /* routines */ - void apply_color_emphasis_and_clamp(bool is_pal_or_dendy, int color_emphasis, double& R, double& G, double& B); - rgb_t nespal_to_RGB(int color_intensity, int color_num, int color_emphasis, bool is_pal_or_dendy); - virtual void init_palette_tables(); - - virtual void read_tile_plane_data(int address, int color); - virtual void shift_tile_plane_data(uint8_t &pix); - virtual void draw_tile_pixel(uint8_t pix, int color, uint32_t back_pen, uint32_t *&dest); - virtual void draw_tile(uint8_t *line_priority, int color_byte, int color_bits, int address, int start_x, uint32_t back_pen, uint32_t *&dest); - virtual void draw_background( uint8_t *line_priority ); - virtual void draw_back_pen(uint32_t* dst, int back_pen); - void draw_background_pen(); - - virtual void read_sprite_plane_data(int address); - virtual void make_sprite_pixel_data(uint8_t &pixel_data, int flipx); - virtual void draw_sprite_pixel(int sprite_xpos, int color, int pixel, uint8_t pixel_data, bitmap_rgb32 &bitmap); - virtual bool is_spritepixel_opaque(int pixel_data, int color); - virtual void draw_sprite_pixel_low(bitmap_rgb32& bitmap, int pixel_data, int pixel, int sprite_xpos, int color, int sprite_index, uint8_t* line_priority); - virtual void draw_sprite_pixel_high(bitmap_rgb32& bitmap, int pixel_data, int pixel, int sprite_xpos, int color, int sprite_index, uint8_t* line_priority); - virtual void read_extra_sprite_bits(int sprite_index); - - virtual int apply_sprite_pattern_page(int index1, int size); - virtual void draw_sprites(uint8_t *line_priority); - void render_scanline(); - virtual void scanline_increment_fine_ycounter(); - void update_visible_enabled_scanline(); - void update_visible_disabled_scanline(); - void update_visible_scanline(); - void update_scanline(); - - void spriteram_dma(address_space &space, const uint8_t page); - void render(bitmap_rgb32 &bitmap, int flipx, int flipy, int sx, int sy, const rectangle &cliprect); - uint32_t screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect); + void spriteram_dma(address_space &space, const u8 page); + void render(bitmap_rgb32 &bitmap, bool flipx, bool flipy, int sx, int sy, const rectangle &cliprect); + u32 screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect); int get_current_scanline() { return m_scanline; } template void set_scanline_callback(T &&... args) { m_scanline_callback_proc.set(std::forward(args)...); m_scanline_callback_proc.resolve(); /* FIXME: if this is supposed to be set at config time, it should be resolved on start */ } @@ -127,14 +98,12 @@ public: // void update_screen(bitmap_t &bitmap, const rectangle &cliprect); - uint16_t get_vram_dest(); - void set_vram_dest(uint16_t dest); - - void ppu2c0x(address_map &map) ATTR_COLD; + u16 get_vram_dest(); + void set_vram_dest(u16 dest); bool in_vblanking() { return (m_scanline >= m_vblank_first_scanline - 1); } protected: - ppu2c0x_device(const machine_config& mconfig, device_type type, const char* tag, device_t* owner, uint32_t clock, address_map_constructor internal_map); + ppu2c0x_device(const machine_config& mconfig, device_type type, const char* tag, device_t* owner, u32 clock, address_map_constructor internal_map); // registers definition enum @@ -172,7 +141,7 @@ protected: }; // construction/destruction - ppu2c0x_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock = 0); + ppu2c0x_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock = 0); virtual void device_start() override ATTR_COLD; virtual void device_config_complete() override; @@ -180,10 +149,42 @@ protected: // device_config_memory_interface overrides virtual space_config_vector memory_space_config() const override; + virtual u32 palette_entries() const noexcept override { return 0x40 * 8; } + TIMER_CALLBACK_MEMBER(hblank_tick); TIMER_CALLBACK_MEMBER(nmi_tick); TIMER_CALLBACK_MEMBER(scanline_tick); + /* routines */ + void apply_color_emphasis_and_clamp(bool is_pal_or_dendy, int color_emphasis, double& R, double& G, double& B); + rgb_t nespal_to_RGB(int color_intensity, int color_num, int color_emphasis, bool is_pal_or_dendy); + virtual void init_palette_tables(); + + virtual void read_tile_plane_data(int address, int color); + virtual void shift_tile_plane_data(u8 &pix); + virtual void draw_tile_pixel(u8 pix, int color, u32 back_pen, u32 *&dest); + virtual void draw_tile(u8 *line_priority, int color_byte, int color_bits, int address, int start_x, u32 back_pen, u32 *&dest); + virtual void draw_background( u8 *line_priority ); + virtual void draw_back_pen(u32* dst, int back_pen); + void draw_background_pen(); + + virtual void read_sprite_plane_data(int address); + virtual void make_sprite_pixel_data(u8 &pixel_data, bool flipx); + virtual void draw_sprite_pixel(int sprite_xpos, int color, int pixel, u8 pixel_data, bitmap_rgb32 &bitmap); + virtual bool is_spritepixel_opaque(int pixel_data, int color); + virtual void draw_sprite_pixel_low(bitmap_rgb32& bitmap, int pixel_data, int pixel, int sprite_xpos, int color, int sprite_index, u8* line_priority); + virtual void draw_sprite_pixel_high(bitmap_rgb32& bitmap, int pixel_data, int pixel, int sprite_xpos, int color, int sprite_index, u8* line_priority); + virtual void read_extra_sprite_bits(int sprite_index); + + virtual int apply_sprite_pattern_page(int index1, int size); + virtual void draw_sprites(u8 *line_priority); + void render_scanline(); + virtual void scanline_increment_fine_ycounter(); + void update_visible_enabled_scanline(); + void update_visible_disabled_scanline(); + void update_visible_scanline(); + void update_scanline(); + // address space configurations const address_space_config m_space_config; @@ -196,47 +197,46 @@ protected: int m_vblank_first_scanline; /* the very first scanline where VBLANK occurs */ // used in rendering - uint8_t m_planebuf[2]; - int m_scanline; /* scanline count */ - std::unique_ptr m_spriteram; /* sprite ram */ + u8 m_planebuf[2]; + s32 m_scanline; /* scanline count */ + std::unique_ptr m_spriteram; /* sprite ram */ int m_videoram_addr_mask; int m_global_refresh_mask; int m_line_write_increment_large; bool m_paletteram_in_ppuspace; // sh6578 doesn't have the palette in PPU space, so various side-effects don't apply - std::vector m_palette_ram; /* shouldn't be in main memory! */ - std::unique_ptr m_bitmap; /* target bitmap */ - int m_regs[PPU_MAX_REG]; /* registers */ - int m_tile_page; /* current tile page */ - int m_back_color; /* background color */ - int m_refresh_data; /* refresh-related */ - int m_x_fine; /* refresh-related */ - int m_toggle; /* used to latch hi-lo scroll */ - int m_tilecount; /* MMC5 can change attributes to subsets of the 34 visible tiles */ + std::vector m_palette_ram; /* shouldn't be in main memory! */ + bitmap_rgb32 m_bitmap; /* target bitmap */ + u8 m_regs[PPU_MAX_REG]; /* registers */ + u32 m_tile_page; /* current tile page */ + u8 m_back_color; /* background color */ + s32 m_refresh_data; /* refresh-related */ + u8 m_x_fine; /* refresh-related */ + bool m_toggle; /* used to latch hi-lo scroll */ + s32 m_tilecount; /* MMC5 can change attributes to subsets of the 34 visible tiles */ latch_delegate m_latch; - uint8_t readbyte(offs_t address); + u8 readbyte(offs_t address); - uint32_t m_nespens[0x40*8]; + void ppu2c0x(address_map &map) ATTR_COLD; private: - inline void writebyte(offs_t address, uint8_t data); - inline uint16_t apply_grayscale_and_emphasis(uint8_t color); - + inline void writebyte(offs_t address, u8 data); + inline u16 apply_grayscale_and_emphasis(u8 color); scanline_delegate m_scanline_callback_proc; /* optional scanline callback */ hblank_delegate m_hblank_callback_proc; /* optional hblank callback */ vidaccess_delegate m_vidaccess_callback_proc; /* optional video access callback */ devcb_write_line m_int_callback; /* nmi access callback from interface */ - int m_refresh_latch; /* refresh-related */ - int m_add; /* vram increment amount */ - int m_videomem_addr; /* videomem address pointer */ - int m_data_latch; /* latched videomem data */ - int m_buffered_data; - int m_sprite_page; /* current sprite page */ - int m_scan_scale; /* scan scale */ - int m_draw_phase; /* MMC5 uses different regs for BG and OAM */ + s32 m_refresh_latch; /* refresh-related */ + s32 m_add; /* vram increment amount */ + u32 m_videomem_addr; /* videomem address pointer */ + u8 m_data_latch; /* latched videomem data */ + u8 m_buffered_data; + u32 m_sprite_page; /* current sprite page */ + s32 m_scan_scale; /* scan scale */ + s32 m_draw_phase; /* MMC5 uses different regs for BG and OAM */ // timers emu_timer *m_hblank_timer; /* hblank period at end of each scanline */ @@ -246,79 +246,81 @@ private: class ppu2c0x_rgb_device : public ppu2c0x_device { protected: - ppu2c0x_rgb_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock = 0); + ppu2c0x_rgb_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock = 0); virtual void init_palette_tables() override; private: - required_region_ptr m_palette_data; + required_region_ptr m_palette_data; }; class ppu2c02_device : public ppu2c0x_device { public: - ppu2c02_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock = 0); + ppu2c02_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock = 0); }; class ppu2c03b_device : public ppu2c0x_rgb_device { public: - ppu2c03b_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock = 0); + ppu2c03b_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock = 0); }; class ppu2c04_device : public ppu2c0x_rgb_device { public: - ppu2c04_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock = 0); + ppu2c04_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock = 0); }; class ppu2c07_device : public ppu2c0x_device { public: - ppu2c07_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock = 0); + ppu2c07_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock = 0); }; class ppupalc_device : public ppu2c0x_device { public: - ppupalc_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock = 0); + ppupalc_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock = 0); }; class ppu2c05_01_device : public ppu2c0x_rgb_device { public: - ppu2c05_01_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock = 0); + ppu2c05_01_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock = 0); }; class ppu2c05_02_device : public ppu2c0x_rgb_device { public: - ppu2c05_02_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock = 0); + ppu2c05_02_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock = 0); }; class ppu2c05_03_device : public ppu2c0x_rgb_device { public: - ppu2c05_03_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock = 0); + ppu2c05_03_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock = 0); }; class ppu2c05_04_device : public ppu2c0x_rgb_device { public: - ppu2c05_04_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock = 0); + ppu2c05_04_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock = 0); }; class ppu2c04_clone_device : public ppu2c0x_device { public: - ppu2c04_clone_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock = 0); + ppu2c04_clone_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock = 0); - virtual uint8_t read(offs_t offset) override; - virtual void write(offs_t offset, uint8_t data) override; - - virtual void draw_background(uint8_t *line_priority) override; - virtual void draw_sprite_pixel(int sprite_xpos, int color, int pixel, uint8_t pixel_data, bitmap_rgb32 &bitmap) override; - virtual void draw_sprites(uint8_t *line_priority) override; - - virtual void init_palette_tables() override; + virtual u8 read(offs_t offset) override; + virtual void write(offs_t offset, u8 data) override; protected: virtual void device_start() override ATTR_COLD; -private: - required_region_ptr m_palette_data; + virtual u32 palette_entries() const noexcept override { return 0x40 * 2; } - std::unique_ptr m_spritebuf; /* buffered sprite ram for next frame */ + virtual void draw_background(u8 *line_priority) override; + virtual void draw_sprite_pixel(int sprite_xpos, int color, int pixel, u8 pixel_data, bitmap_rgb32 &bitmap) override; + virtual void draw_sprites(u8 *line_priority) override; + + virtual void init_palette_tables() override; + +private: + required_region_ptr m_palette_data; + + std::unique_ptr m_spritebuf; /* buffered sprite ram for next frame */ }; // device type definition diff --git a/src/devices/video/ppu2c0x_sh6578.cpp b/src/devices/video/ppu2c0x_sh6578.cpp index b2bbc6d995b..8e5a375f707 100644 --- a/src/devices/video/ppu2c0x_sh6578.cpp +++ b/src/devices/video/ppu2c0x_sh6578.cpp @@ -59,6 +59,8 @@ void ppu_sh6578_device::device_start() m_palette_ram[i] = 0x00; save_item(NAME(m_palette_ram)); + save_item(NAME(m_extplanebuf)); + save_item(NAME(m_colsel_pntstart)); } void ppu_sh6578_device::device_reset() @@ -73,10 +75,9 @@ void ppu_sh6578_device::scanline_increment_fine_ycounter() m_refresh_data += 0x1000; /* if it's rolled, increment the coarse y-scroll */ - if (m_refresh_data & 0x8000) + if (BIT(m_refresh_data, 15)) { - uint16_t tmp; - tmp = (m_refresh_data & 0x03e0) + 0x20; + const uint16_t tmp = (m_refresh_data & 0x03e0) + 0x20; m_refresh_data &= 0x7c1f; if (tmp == 0x0400) @@ -90,8 +91,7 @@ void ppu_sh6578_device::scanline_increment_fine_ycounter() void ppu_sh6578_device::draw_sprite_pixel(int sprite_xpos, int color, int pixel, uint8_t pixel_data, bitmap_rgb32& bitmap) { - uint8_t palval = m_palette_ram[(pixel_data | color << 2)] & 0x3f; - bitmap.pix(m_scanline, sprite_xpos + pixel) = m_nespens[palval]; + bitmap.pix(m_scanline, sprite_xpos + pixel) = pen_color(m_palette_ram[(pixel_data | color << 2)] & 0x3f); } void ppu_sh6578_device::read_tile_plane_data(int address, int color) @@ -110,7 +110,7 @@ void ppu_sh6578_device::draw_tile(uint8_t* line_priority, int color_byte, int co { int color = color_byte; - if (m_colsel_pntstart & 0x80) + if (BIT(m_colsel_pntstart, 7)) { color &= 0xc; } @@ -146,11 +146,9 @@ void ppu_sh6578_device::draw_tile(uint8_t* line_priority, int color_byte, int co if ((start_x + i) >= 0 && (start_x + i) < VISIBLE_SCREEN_WIDTH) { - pen_t pen; + rgb_t pen; - uint8_t palval; - - palval = m_palette_ram[(pix | color << 2)] & 0x3f; + const uint8_t palval = m_palette_ram[(pix | color << 2)] & 0x3f; bool trans = false; if ((palval & 0x1f) == 0x1f) @@ -158,12 +156,12 @@ void ppu_sh6578_device::draw_tile(uint8_t* line_priority, int color_byte, int co if (!trans) { - pen = m_nespens[palval]; + pen = pen_color(palval); } else { - uint8_t palval = m_palette_ram[0x0] & 0x3f; - pen = m_nespens[palval]; + const uint8_t palval = m_palette_ram[0x0] & 0x3f; + pen = pen_color(palval); } *dest = pen; @@ -178,8 +176,6 @@ void ppu_sh6578_device::draw_tile(uint8_t* line_priority, int color_byte, int co void ppu_sh6578_device::draw_background(uint8_t* line_priority) { - bitmap_rgb32& bitmap = *m_bitmap; - uint8_t color_mask = 0xff; //const pen_t* color_table; @@ -197,34 +193,30 @@ void ppu_sh6578_device::draw_background(uint8_t* line_priority) /* cache the background pen */ - pen_t back_pen = m_nespens[m_back_color & color_mask]; + const pen_t back_pen = pen_color(m_back_color & color_mask); /* determine where in the nametable to start drawing from */ /* based on the current scanline and scroll regs */ - uint8_t scroll_x_coarse = m_refresh_data & 0x001f; - uint8_t scroll_y_coarse = (m_refresh_data & 0x03e0) >> 5; - uint16_t nametable = (m_refresh_data & 0x0c00); - uint8_t scroll_y_fine = (m_refresh_data & 0x7000) >> 12; + const uint8_t scroll_x_coarse = m_refresh_data & 0x001f; + const uint8_t scroll_y_coarse = (m_refresh_data & 0x03e0) >> 5; + const uint16_t nametable = (m_refresh_data & 0x0c00); + const uint8_t scroll_y_fine = (m_refresh_data & 0x7000) >> 12; int x = scroll_x_coarse; /* get the tile index */ - int tile_index = (nametable<<1) + scroll_y_coarse * 64; + int tile_index = (nametable << 1) + scroll_y_coarse * 64; /* set up dest */ int start_x = (m_x_fine ^ 0x07) - 7; - uint32_t* dest = &bitmap.pix(m_scanline, start_x); + uint32_t* dest = &m_bitmap.pix(m_scanline, start_x); m_tilecount = 0; /* draw the 32 or 33 tiles that make up a line */ while (m_tilecount < 34) { - int color_byte; - int index1; - int page2, address; - - index1 = tile_index + (x << 1); + int index1 = tile_index + (x << 1); if (m_colsel_pntstart & 1) { @@ -237,14 +229,14 @@ void ppu_sh6578_device::draw_background(uint8_t* line_priority) } // page2 is the output of the nametable read (this section is the FIRST read per tile!) - page2 = readbyte(index1); + const int page2 = readbyte(index1); /* Figure out which byte in the color table to use */ - color_byte = readbyte(index1 + 1); + const int color_byte = readbyte(index1 + 1); if (start_x < VISIBLE_SCREEN_WIDTH) { - address = ((page2 | (color_byte<<8)) & 0x0fff) << 4; + int address = ((page2 | (color_byte<<8)) & 0x0fff) << 4; // plus something that accounts for y address += scroll_y_fine; @@ -266,7 +258,7 @@ void ppu_sh6578_device::draw_background(uint8_t* line_priority) /* if the left 8 pixels for the background are off, blank 'em */ if (!(m_regs[PPU_CONTROL1] & PPU_CONTROL1_BACKGROUND_L8)) { - dest = &bitmap.pix(m_scanline); + dest = &m_bitmap.pix(m_scanline); for (int i = 0; i < 8; i++) { *(dest++) = back_pen; diff --git a/src/devices/video/ppu2c0x_sh6578.h b/src/devices/video/ppu2c0x_sh6578.h index 8a673280b2a..14543df21b0 100644 --- a/src/devices/video/ppu2c0x_sh6578.h +++ b/src/devices/video/ppu2c0x_sh6578.h @@ -24,22 +24,22 @@ public: protected: ppu_sh6578_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock); - void ppu_internal_map(address_map &map) ATTR_COLD; - -private: virtual void device_start() override ATTR_COLD; virtual void device_reset() override ATTR_COLD; + virtual void draw_sprite_pixel(int sprite_xpos, int color, int pixel, uint8_t pixel_data, bitmap_rgb32 &bitmap) override; + //virtual void draw_sprites(uint8_t *line_priority) override; + virtual void draw_background(uint8_t *line_priority) override; + virtual int apply_sprite_pattern_page(int index1, int size) override; + virtual void read_sprite_plane_data(int address) override; + + void ppu_internal_map(address_map &map) ATTR_COLD; + +private: void scanline_increment_fine_ycounter() override; void read_tile_plane_data(int address, int color) override; - void draw_tile(uint8_t* line_priority, int color_byte, int color_bits, int address, int start_x, uint32_t back_pen, uint32_t*& dest) override; - - virtual void draw_sprite_pixel(int sprite_xpos, int color, int pixel, uint8_t pixel_data, bitmap_rgb32& bitmap) override; - //virtual void draw_sprites(uint8_t* line_priority) override; - virtual void draw_background(uint8_t* line_priority) override; - virtual int apply_sprite_pattern_page(int index1, int size) override; - virtual void read_sprite_plane_data(int address) override; + void draw_tile(uint8_t *line_priority, int color_byte, int color_bits, int address, int start_x, uint32_t back_pen, uint32_t *&dest) override; uint8_t m_extplanebuf[2]; uint8_t m_colsel_pntstart; @@ -48,7 +48,7 @@ private: class ppu_sh6578pal_device : public ppu_sh6578_device { public: - ppu_sh6578pal_device(const machine_config& mconfig, const char* tag, device_t* owner, uint32_t clock); + ppu_sh6578pal_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); }; DECLARE_DEVICE_TYPE(PPU_SH6578, ppu_sh6578_device) diff --git a/src/devices/video/ppu2c0x_vt.cpp b/src/devices/video/ppu2c0x_vt.cpp index a4754b421d7..80616719ac1 100644 --- a/src/devices/video/ppu2c0x_vt.cpp +++ b/src/devices/video/ppu2c0x_vt.cpp @@ -146,10 +146,10 @@ void ppu_vt03_device::init_vtxx_rgb555_palette_tables() { for (int palval = 0; palval < 0x8000; palval++) { - // uint16_t rgbval = (m_palette_ram[i & 0x7f] & 0xff) | ((m_palette_ram[(i & 0x7f) + 0x80] & 0xff) << 8); - uint8_t blue = (palval & 0x001f) << 3; - uint8_t green = (palval & 0x3e0) >> 2; - uint8_t red = (palval & 0x7C00) >> 7; + //uint16_t rgbval = (m_palette_ram[i & 0x7f] & 0xff) | ((m_palette_ram[(i & 0x7f) + 0x80] & 0xff) << 8); + const uint8_t blue = (palval & 0x001f) << 3; + const uint8_t green = (palval & 0x3e0) >> 2; + const uint8_t red = (palval & 0x7C00) >> 7; // TODO: apply emphasis values if they work in this mode m_vtpens_rgb555[entry] = rgb_t(red, green, blue); @@ -166,9 +166,9 @@ void ppu_vt03_device::init_vtxx_rgb444_palette_tables() for (int palval = 0; palval < 0x1000; palval++) { //uint16_t rgbval = (m_palette_ram[i & 0x7f] & 0x3f) | ((m_palette_ram[(i & 0x7f) + 0x80] & 0x3f) << 6); - uint8_t red = (palval & 0x000f) << 4; - uint8_t green = (palval & 0x0f0); - uint8_t blue = (palval & 0xf00) >> 4; + const uint8_t red = (palval & 0x000f) << 4; + const uint8_t green = (palval & 0x0f0); + const uint8_t blue = (palval & 0xf00) >> 4; // TODO: apply emphasis values if they work in this mode m_vtpens_rgb444[entry] = rgb_t(red, green, blue); @@ -205,7 +205,7 @@ void ppu_vt03_device::init_vt03_palette_tables(int palmode) float fLuma = (nLuma - 4) / 9.625; // Value determined from matching saturation =0 phases 1-12 float fChroma = nChroma / 18.975; // Value determined from matching phases 0 and 13 across all luminance and saturation levels - float fPhase = ((nPhase - 2) * 30.0 + phaseOffset) * M_PI / 180.0; + const float fPhase = ((nPhase - 2) * 30.0 + phaseOffset) * M_PI / 180.0; if (palmode == 1) { @@ -223,8 +223,8 @@ void ppu_vt03_device::init_vt03_palette_tables(int palmode) if (nPhase == 13) Y -= fChroma; // Phase 13 is the lower bound of the waveform if (nPhase >= 14) Y = 0.0; // Phases 14 and 15 always black - float V = sin(fPhase) * C * 1.05; // 1.05 needed to get closer to EmuVT palette's color levels in phases 1-12 - float U = cos(fPhase) * C * 1.05; + const float V = sin(fPhase) * C * 1.05; // 1.05 needed to get closer to EmuVT palette's color levels in phases 1-12 + const float U = cos(fPhase) * C * 1.05; float R = Y + 1.1400 * V + 0.0000 * U; float G = Y - 0.5807 * V - 0.3940 * U; float B = Y - 0.0000 * V + 2.0290 * U; @@ -234,15 +234,15 @@ void ppu_vt03_device::init_vt03_palette_tables(int palmode) if (G > 1.0) G = 1.0; if (B < 0.0) B = 0.0; if (B > 1.0) B = 1.0; - int RV = R * 255.0; - int GV = G * 255.0; - int BV = B * 255.0; + const int RV = R * 255.0; + const int GV = G * 255.0; + const int BV = B * 255.0; // does this really apply to the VT palette? //bool is_pal = m_scanlines_per_frame != NTSC_SCANLINES_PER_FRAME; //apply_color_emphasis_and_clamp(is_pal, color_emphasis, R, G, B); - m_vtpens[entry] = rgb_t(RV, GV, BV); + set_pen_color(YUV444_COLOR + entry, rgb_t(RV, GV, BV)); entry++; } } @@ -258,6 +258,10 @@ void ppu_vt03_device::device_start() m_palette_ram[i] = 0x00; save_item(NAME(m_palette_ram)); + save_item(NAME(m_read_bg4_bg3)); + save_item(NAME(m_va34)); + save_item(NAME(m_extplanebuf)); + save_item(NAME(m_extra_sprite_bits)); save_item(NAME(m_201x_regs)); init_vt03_palette_tables(0); @@ -289,7 +293,7 @@ void ppu_vt03_device::device_reset() set_201x_reg(i, 0x00); m_read_bg4_bg3 = 0; - m_va34 = 0; + m_va34 = false; } @@ -306,26 +310,26 @@ uint8_t ppu_vt03_device::get_va34() void ppu_vt03_device::read_sprite_plane_data(int address) { - m_va34 = 0; + m_va34 = false; m_planebuf[0] = m_read_sp((address + 0) & 0x1fff); m_planebuf[1] = m_read_sp((address + 8) & 0x1fff); - int is4bpp = get_201x_reg(0x0) & 0x04; + const bool is4bpp = BIT(get_201x_reg(0x0), 2); if (is4bpp) { - m_va34 = 1; + m_va34 = true; m_extplanebuf[0] = m_read_sp((address + 0) & 0x1fff); m_extplanebuf[1] = m_read_sp((address + 8) & 0x1fff); } } -void ppu_vt03_device::make_sprite_pixel_data(uint8_t& pixel_data, int flipx) +void ppu_vt03_device::make_sprite_pixel_data(uint8_t& pixel_data, bool flipx) { ppu2c0x_device::make_sprite_pixel_data(pixel_data, flipx); - int is4bpp = get_201x_reg(0x0) & 0x04; - int is16pix = get_201x_reg(0x0) & 0x01; + const bool is4bpp = BIT(get_201x_reg(0x0), 2); + const bool is16pix = BIT(get_201x_reg(0x0), 0); if (is4bpp) { @@ -338,8 +342,8 @@ void ppu_vt03_device::make_sprite_pixel_data(uint8_t& pixel_data, int flipx) if (is16pix) { - uint8_t pix0 = pixel_data & 0x03; - uint8_t pix1 = (pixel_data >> 5) & 0x03; + const uint8_t pix0 = pixel_data & 0x03; + const uint8_t pix1 = (pixel_data >> 5) & 0x03; pixel_data = pix1 | (pix0 << 5); } } @@ -354,14 +358,14 @@ void ppu_vt03_device::make_sprite_pixel_data(uint8_t& pixel_data, int flipx) void ppu_vt03_device::draw_sprite_pixel(int sprite_xpos, int color, int pixel, uint8_t pixel_data, bitmap_rgb32& bitmap) { - int is4bpp = get_201x_reg(0x0) & 0x04; - int is16pix = get_201x_reg(0x0) & 0x01; + const bool is4bpp = BIT(get_201x_reg(0x0), 2); + const bool is16pix = BIT(get_201x_reg(0x0), 0); if (is4bpp) { if (!is16pix) { - uint8_t pen = pixel_data + (4 * color); + const uint8_t pen = pixel_data + (4 * color); draw_tile_pixel_inner(pen, &bitmap.pix(m_scanline, sprite_xpos + pixel)); } else @@ -371,13 +375,13 @@ void ppu_vt03_device::draw_sprite_pixel(int sprite_xpos, int color, int pixel, u cliprect - not seen used yet */ if ((pixel_data & 0x03) != 0) { - uint8_t pen = (pixel_data & 0x03) + (4 * color); + const uint8_t pen = (pixel_data & 0x03) + (4 * color); draw_tile_pixel_inner(pen, &bitmap.pix(m_scanline, sprite_xpos + pixel)); } if (((pixel_data >> 5) & 0x03) != 0) { - uint8_t pen = ((pixel_data >> 5) & 0x03) + (4 * color); + const uint8_t pen = ((pixel_data >> 5) & 0x03) + (4 * color); draw_tile_pixel_inner(pen, &bitmap.pix(m_scanline, sprite_xpos + pixel + 8)); } //ppu2c0x_device::draw_sprite_pixel(sprite_xpos, color, pixel, pixel_data & 0x03, bitmap); @@ -392,7 +396,7 @@ void ppu_vt03_device::draw_sprite_pixel(int sprite_xpos, int color, int pixel, u void ppu_vt03_device::read_tile_plane_data(int address, int color) { - int is4bpp = get_201x_reg(0x0) & 0x02; + const bool is4bpp = BIT(get_201x_reg(0x0), 1); if (m_201x_regs[0] & 0x10) // extended mode m_read_bg4_bg3 = color; @@ -401,16 +405,16 @@ void ppu_vt03_device::read_tile_plane_data(int address, int color) if (is4bpp) { - m_va34 = 0; + m_va34 = false; m_planebuf[0] = m_read_bg((address & 0x1fff)); m_planebuf[1] = m_read_bg((address + 8) & 0x1fff); - m_va34 = 1; + m_va34 = true; m_extplanebuf[0] = m_read_bg((address & 0x1fff)); m_extplanebuf[1] = m_read_bg((address + 8) & 0x1fff); } else { - m_va34 = 0; + m_va34 = false; m_planebuf[0] = m_read_bg((address & 0x1fff)); m_planebuf[1] = m_read_bg((address + 8) & 0x1fff); } @@ -418,7 +422,7 @@ void ppu_vt03_device::read_tile_plane_data(int address, int color) void ppu_vt03_device::shift_tile_plane_data(uint8_t& pix) { - int is4bpp = get_201x_reg(0x0) & 0x02; + const bool is4bpp = BIT(get_201x_reg(0x0), 1); ppu2c0x_device::shift_tile_plane_data(pix); @@ -441,21 +445,18 @@ void ppu_vt03_device::draw_back_pen(uint32_t* dst, int back_pen) else { // in normal modes we still have the data from the palette writes as the 'backpen' so treat it as before - uint32_t pix; - pix = m_nespens[back_pen & 0x1ff]; - *dst = pix; + *dst = pen_color(back_pen & 0x1ff); } } void ppu_vt03_device::draw_tile_pixel_inner(uint8_t pen, uint32_t *dest) { - if (m_201x_regs[0] & 0x80) + if (BIT(m_201x_regs[0], 7)) { if (m_pal_mode == PAL_MODE_NEW_RGB) // unknown newer VT mode { - uint32_t palval; - palval = (m_palette_ram[pen & 0x7f] & 0xff) | ((m_palette_ram[(pen & 0x7f) + 0x80] & 0x7f) << 8); + uint32_t palval = (m_palette_ram[pen & 0x7f] & 0xff) | ((m_palette_ram[(pen & 0x7f) + 0x80] & 0x7f) << 8); // does grayscale mode exist here? (we haven't calculated any colours for it) //if (m_regs[PPU_CONTROL1] & PPU_CONTROL1_DISPLAY_MONO) @@ -464,14 +465,11 @@ void ppu_vt03_device::draw_tile_pixel_inner(uint8_t pen, uint32_t *dest) // apply colour emphasis (does it really exist here?) (we haven't calculated any colours for it, so ths has no effect) palval |= ((m_regs[PPU_CONTROL1] & PPU_CONTROL1_COLOR_EMPHASIS) << 10); - uint32_t pix; - pix = m_vtpens_rgb555[palval & 0x3ffff]; - *dest = pix; + *dest = m_vtpens_rgb555[palval & 0x3ffff]; } else if (m_pal_mode == PAL_MODE_NEW_RGB12) // unknown newer VT mode { - uint32_t palval; - palval = (m_palette_ram[pen & 0x7f] & 0x3f) | ((m_palette_ram[(pen & 0x7f) + 0x80] & 0x3f) << 6); + uint32_t palval = (m_palette_ram[pen & 0x7f] & 0x3f) | ((m_palette_ram[(pen & 0x7f) + 0x80] & 0x3f) << 6); // does grayscale mode exist here? (we haven't calculated any colours for it) //if (m_regs[PPU_CONTROL1] & PPU_CONTROL1_DISPLAY_MONO) @@ -480,14 +478,11 @@ void ppu_vt03_device::draw_tile_pixel_inner(uint8_t pen, uint32_t *dest) // apply colour emphasis (does it really exist here?) (we haven't calculated any colours for it, so ths has no effect) palval |= ((m_regs[PPU_CONTROL1] & PPU_CONTROL1_COLOR_EMPHASIS) << 7); - uint32_t pix; - pix = m_vtpens_rgb444[palval & 0x7fff]; - *dest = pix; + *dest = m_vtpens_rgb444[palval & 0x7fff]; } else // VT03 mode { - uint32_t palval; - palval = (m_palette_ram[pen & 0x7f] & 0x3f) | ((m_palette_ram[(pen & 0x7f) + 0x80] & 0x3f) << 6); + uint32_t palval = (m_palette_ram[pen & 0x7f] & 0x3f) | ((m_palette_ram[(pen & 0x7f) + 0x80] & 0x3f) << 6); // does grayscale mode exist here? (we haven't calculated any colours for it) //if (m_regs[PPU_CONTROL1] & PPU_CONTROL1_DISPLAY_MONO) @@ -496,15 +491,12 @@ void ppu_vt03_device::draw_tile_pixel_inner(uint8_t pen, uint32_t *dest) // apply colour emphasis (does it really exist here?) (we calculate values for it when building the palette lookup) palval |= ((m_regs[PPU_CONTROL1] & PPU_CONTROL1_COLOR_EMPHASIS) << 7); - uint32_t pix; - pix = m_vtpens[palval & 0x7fff]; - *dest = pix; + *dest = pen_color(YUV444_COLOR + (palval & 0x7fff)); } } else // old colour compatible mode { - uint16_t palval; - palval = (m_palette_ram[pen & 0x7f] & 0x3f); + uint16_t palval = (m_palette_ram[pen & 0x7f] & 0x3f); if (m_regs[PPU_CONTROL1] & PPU_CONTROL1_DISPLAY_MONO) palval &= 0x30; @@ -512,14 +504,12 @@ void ppu_vt03_device::draw_tile_pixel_inner(uint8_t pen, uint32_t *dest) // apply colour emphasis palval |= ((m_regs[PPU_CONTROL1] & PPU_CONTROL1_COLOR_EMPHASIS) << 1); - uint32_t pix; - pix = m_nespens[palval & 0x1ff]; - *dest = pix; + *dest = pen_color(palval & 0x1ff); } } void ppu_vt03_device::draw_tile_pixel(uint8_t pix, int color, uint32_t back_pen, uint32_t*& dest) { - int is4bpp = get_201x_reg(0x0) & 0x02; + const bool is4bpp = BIT(get_201x_reg(0x0), 1); if (!is4bpp) { diff --git a/src/devices/video/ppu2c0x_vt.h b/src/devices/video/ppu2c0x_vt.h index d83120fe7df..7eb47924ab6 100644 --- a/src/devices/video/ppu2c0x_vt.h +++ b/src/devices/video/ppu2c0x_vt.h @@ -39,24 +39,6 @@ public: virtual uint8_t palette_read(offs_t offset) override; virtual void palette_write(offs_t offset, uint8_t data) override; - void init_vt03_palette_tables(int palmode); - void init_vtxx_rgb555_palette_tables(); - void init_vtxx_rgb444_palette_tables(); - - virtual void read_tile_plane_data(int address, int color) override; - virtual void shift_tile_plane_data(uint8_t &pix) override; - virtual void draw_tile_pixel(uint8_t pix, int color, uint32_t back_pen, uint32_t *&dest) override; - inline void draw_tile_pixel_inner(uint8_t pen, uint32_t *dest); - virtual void draw_back_pen(uint32_t* dst, int back_pen) override; - - virtual void read_sprite_plane_data(int address) override; - virtual void make_sprite_pixel_data(uint8_t &pixel_data, int flipx) override; - virtual void draw_sprite_pixel(int sprite_xpos, int color, int pixel, uint8_t pixel_data, bitmap_rgb32 &bitmap) override; - virtual void read_extra_sprite_bits(int sprite_index) override; - - virtual void device_start() override ATTR_COLD; - virtual void device_reset() override ATTR_COLD; - void set_201x_reg(int reg, uint8_t data); uint8_t get_201x_reg(int reg); @@ -68,10 +50,25 @@ public: bool get_is_50hz() { return m_is_50hz; } protected: + virtual void device_start() override ATTR_COLD; + virtual void device_reset() override ATTR_COLD; + + virtual u32 palette_entries() const noexcept override { return (0x40 * 8) + (0x1000 * 8); } + + virtual void read_tile_plane_data(int address, int color) override; + virtual void shift_tile_plane_data(uint8_t &pix) override; + virtual void draw_tile_pixel(uint8_t pix, int color, uint32_t back_pen, uint32_t *&dest) override; + inline void draw_tile_pixel_inner(uint8_t pen, uint32_t *dest); + virtual void draw_back_pen(uint32_t* dst, int back_pen) override; + + virtual void read_sprite_plane_data(int address) override; + virtual void make_sprite_pixel_data(uint8_t &pixel_data, bool flipx) override; + virtual void draw_sprite_pixel(int sprite_xpos, int color, int pixel, uint8_t pixel_data, bitmap_rgb32 &bitmap) override; + virtual void read_extra_sprite_bits(int sprite_index) override; + bool m_is_pal; bool m_is_50hz; - uint32_t m_vtpens[0x1000*8]; uint32_t m_vtpens_rgb555[0x8000*8]; uint32_t m_vtpens_rgb444[0x1000*8]; @@ -79,8 +76,8 @@ private: devcb_read8 m_read_bg; devcb_read8 m_read_sp; - int m_read_bg4_bg3; - int m_va34; + int32_t m_read_bg4_bg3; + bool m_va34; uint8_t m_extplanebuf[2]; uint8_t m_extra_sprite_bits; @@ -92,6 +89,11 @@ private: vtxx_pal_mode m_pal_mode = PAL_MODE_VT0x; void set_2010_reg(uint8_t data); + void init_vt03_palette_tables(int palmode); + void init_vtxx_rgb555_palette_tables(); + void init_vtxx_rgb444_palette_tables(); + + static constexpr unsigned YUV444_COLOR = (0x40 * 8); }; class ppu_vt03pal_device : public ppu_vt03_device {