diff options
author | cam900 <dbtlrchl@naver.com> | 2020-10-25 22:49:49 +0900 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-10-26 00:49:49 +1100 |
commit | 62d9564619d6a91e4be07a3833e627ec652a9bd0 (patch) | |
tree | 9ce80ad40bf0d6d4760ade37dd61aae9558c7908 /src/devices/video | |
parent | 16f71a3a8ee0e5969c984be3164a6f5171d77abe (diff) |
snes_ppu.cpp: Use device_palette_interface for Palette handling (#7375)
Use device_palette_interface for palette, fixed CGRAM size and direct color behavior
Diffstat (limited to 'src/devices/video')
-rw-r--r-- | src/devices/video/snes_ppu.cpp | 94 | ||||
-rw-r--r-- | src/devices/video/snes_ppu.h | 11 |
2 files changed, 60 insertions, 45 deletions
diff --git a/src/devices/video/snes_ppu.cpp b/src/devices/video/snes_ppu.cpp index e0b4eb544b1..1a8083195f3 100644 --- a/src/devices/video/snes_ppu.cpp +++ b/src/devices/video/snes_ppu.cpp @@ -83,9 +83,8 @@ #define SNES_CLIP_ALWAYS 3 #define SNES_VRAM_SIZE 0x10000 /* 64kb of video ram */ -#define SNES_CGRAM_SIZE 0x202 /* 256 16-bit colours + 1 tacked on 16-bit colour for fixed colour */ +#define SNES_CGRAM_SIZE 0x200 /* 256 16-bit colours */ #define SNES_OAM_SIZE 0x440 /* 1088 bytes of Object Attribute Memory */ -#define FIXED_COLOUR 256 /* Position in cgram for fixed colour */ /* Definitions for PPU Memory-Mapped registers */ @@ -193,6 +192,7 @@ DEFINE_DEVICE_TYPE(SNES_PPU, snes_ppu_device, "snes_ppu", "SNES PPU") snes_ppu_device::snes_ppu_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : device_t(mconfig, SNES_PPU, tag, owner, clock) , device_video_interface(mconfig, *this) + , device_palette_interface(mconfig, *this) , m_openbus_cb(*this) , m_options(*this, ":OPTIONS") , m_debug1(*this, ":DEBUG1") @@ -227,11 +227,29 @@ void snes_ppu_device::device_start() uint8_t ar = (uint8_t)(luma * r + 0.5); uint8_t ag = (uint8_t)(luma * g + 0.5); uint8_t ab = (uint8_t)(luma * b + 0.5); - m_light_table[l][r << 10 | g << 5 | b << 0] = ar << 10 | ag << 5 | ab << 0; + m_light_table[l][r << 0 | g << 5 | b << 10] = ar << 0 | ag << 5 | ab << 10; } } } } + // initialize direct colours + for (int rgb = 0; rgb < 32*32*32; rgb++) + { + set_indirect_color(rgb, pal555(rgb, 0, 5, 10)); + } + for (uint8_t group = 0; group < 8; group++) + { + for (int c = 0; c < 256; c++) + { + //palette = -------- BBGGGRRR + //group = -------- -----bgr + //output = 0BBb00GG Gg0RRRr0 + const u16 direct = (c << 7 & 0x6000) + (group << 10 & 0x1000) + + (c << 4 & 0x0380) + (group << 5 & 0x0040) + + (c << 2 & 0x001c) + (group << 1 & 0x0002); + set_pen_indirect(DIRECT_COLOUR + c + (group * 256), direct); + } + } for (int i = 0; i < ARRAY_LENGTH(m_scanlines); i++) { @@ -393,6 +411,10 @@ void snes_ppu_device::device_reset() /* Init Palette RAM */ memset((uint8_t *)m_cgram.get(), 0, SNES_CGRAM_SIZE); + for (int i = 0; i < 256; i++) + set_pen_indirect(i, m_cgram[i]); + + set_pen_indirect(FIXED_COLOUR, 0); // other initializations to 0 memset(m_regs, 0, sizeof(m_regs)); @@ -729,11 +751,11 @@ void snes_ppu_device::update_line( uint16_t curline, uint8_t layer_idx, uint8_t mosaic_priority = tile_priority; if (direct_color_mode) { - mosaic_color = direct_color(palette_number, mosaic_palette); + mosaic_color = direct_color(mosaic_palette, palette_number); } else { - mosaic_color = m_cgram[(palette_index + mosaic_palette) % FIXED_COLOUR]; + mosaic_color = pen_indirect((palette_index + mosaic_palette) & 0xff); } } if (!mosaic_palette) continue; @@ -827,11 +849,11 @@ void snes_ppu_device::update_line_mode7( uint16_t curline, uint8_t layer_idx ) mosaic_priority = priority; if (m_direct_color && layer_idx == SNES_BG1) { - mosaic_color = direct_color(0, palette); + mosaic_color = direct_color(palette, 0); } else { - mosaic_color = m_cgram[palette]; + mosaic_color = pen_indirect(palette); } } if (!mosaic_palette) continue; @@ -999,8 +1021,8 @@ void snes_ppu_device::update_objects( uint16_t curline ) { if (!pribuf[x]) continue; int blend = (palbuf[x] < 192) ? 1 : 0; - if (m_layer[SNES_OAM].main_bg_enabled && window_above[x] == 0) plot_above(x, SNES_OAM, pribuf[x], m_cgram[palbuf[x]], blend); - if (m_layer[SNES_OAM].sub_bg_enabled && window_below[x] == 0) plot_below(x, SNES_OAM, pribuf[x], m_cgram[palbuf[x]], blend); + if (m_layer[SNES_OAM].main_bg_enabled && window_above[x] == 0) plot_above(x, SNES_OAM, pribuf[x], pen_indirect(palbuf[x]), blend); + if (m_layer[SNES_OAM].sub_bg_enabled && window_below[x] == 0) plot_below(x, SNES_OAM, pribuf[x], pen_indirect(palbuf[x]), blend); } } @@ -1287,8 +1309,8 @@ void snes_ppu_device::refresh_scanline( bitmap_rgb32 &bitmap, uint16_t curline ) #endif const bool hires = m_mode == 5 || m_mode == 6 || m_pseudo_hires; - uint16_t above_color = m_cgram[0]; - uint16_t below_color = hires ? m_cgram[0] : m_cgram[FIXED_COLOUR]; + uint16_t above_color = pen_indirect(0); + uint16_t below_color = hires ? pen_indirect(0) : pen_indirect(FIXED_COLOUR); for (int x = 0; x < SNES_SCR_WIDTH; x++) { above->buffer[x] = above_color; @@ -1319,45 +1341,30 @@ void snes_ppu_device::refresh_scanline( bitmap_rgb32 &bitmap, uint16_t curline ) if (!hires) { const uint16_t c = luma[pixel(x, above, below, window_above, window_below)]; - const int r = (c & 0x1f); - const int g = (c & 0x3e0) >> 5; - const int b = (c & 0x7c00) >> 10; - bitmap.pix(0, x * 2 + 0) = rgb_t(pal5bit(r), pal5bit(g), pal5bit(b)); - bitmap.pix(0, x * 2 + 1) = rgb_t(pal5bit(r), pal5bit(g), pal5bit(b)); + bitmap.pix(0, x * 2 + 0) = indirect_color(c & 0x7fff); + bitmap.pix(0, x * 2 + 1) = indirect_color(c & 0x7fff); } else if (!blurring) { const uint16_t c0 = luma[pixel(x, below, above, window_above, window_below)]; const uint16_t c1 = luma[pixel(x, above, below, window_above, window_below)]; - const int r0 = (c0 & 0x1f); - const int r1 = (c1 & 0x1f); - const int g0 = (c0 & 0x3e0) >> 5; - const int g1 = (c1 & 0x3e0) >> 5; - const int b0 = (c0 & 0x7c00) >> 10; - const int b1 = (c1 & 0x7c00) >> 10; - - bitmap.pix(0, x * 2 + 0) = rgb_t(pal5bit(r0), pal5bit(g0), pal5bit(b0)); - bitmap.pix(0, x * 2 + 1) = rgb_t(pal5bit(r1), pal5bit(g1), pal5bit(b1)); + + bitmap.pix(0, x * 2 + 0) = indirect_color(c0 & 0x7fff); + bitmap.pix(0, x * 2 + 1) = indirect_color(c1 & 0x7fff); } else { uint16_t curr = luma[pixel(x, below, above, window_above, window_below)]; uint16_t c0 = (prev + curr - ((prev ^ curr) & 0x0421)) >> 1; - const int r0 = (c0 & 0x1f); - const int g0 = (c0 & 0x3e0) >> 5; - const int b0 = (c0 & 0x7c00) >> 10; - bitmap.pix(0, x * 2 + 0) = rgb_t(pal5bit(r0), pal5bit(g0), pal5bit(b0)); + bitmap.pix(0, x * 2 + 0) = indirect_color(c0 & 0x7fff); prev = curr; curr = luma[pixel(x, above, below, window_above, window_below)]; uint16_t c1 = (prev + curr - ((prev ^ curr) & 0x0421)) >> 1; - const int r1 = (c1 & 0x1f); - const int g1 = (c1 & 0x3e0) >> 5; - const int b1 = (c1 & 0x7c00) >> 10; - bitmap.pix(0, x * 2 + 1) = rgb_t(pal5bit(r1), pal5bit(g1), pal5bit(b1)); + bitmap.pix(0, x * 2 + 1) = indirect_color(c1 & 0x7fff); prev = curr; } @@ -1372,7 +1379,7 @@ uint16_t snes_ppu_device::pixel(uint16_t x, SNES_SCANLINE *above, SNES_SCANLINE if (!window_above[x]) above->buffer[x] = 0; if (!window_below[x]) return above->buffer[x]; if (!m_layer[above->layer[x]].color_math || (above->layer[x] == SNES_OAM && above->blend_exception[x])) return above->buffer[x]; - if (!m_sub_add_mode) return blend(above->buffer[x], m_cgram[FIXED_COLOUR], BIT(m_color_modes, 0) != 0 && window_above[x] != 0); + if (!m_sub_add_mode) return blend(above->buffer[x], pen_indirect(FIXED_COLOUR), BIT(m_color_modes, 0) != 0 && window_above[x] != 0); return blend(above->buffer[x], below->buffer[x], BIT(m_color_modes, 0) != 0 && window_above[x] != 0 && below->layer[x] != SNES_COLOR); } @@ -1723,6 +1730,7 @@ void snes_ppu_device::cgram_write(offs_t offset, uint8_t data) data &= 0x7f; ((uint8_t *)m_cgram.get())[offset] = data; + set_pen_indirect(offset >> 1, m_cgram[offset >> 1] & 0x7fff); } uint16_t snes_ppu_device::direct_color(uint16_t palette, uint16_t group) @@ -1730,9 +1738,7 @@ uint16_t snes_ppu_device::direct_color(uint16_t palette, uint16_t group) //palette = -------- BBGGGRRR //group = -------- -----bgr //output = 0BBb00GG Gg0RRRr0 - return (palette << 7 & 0x6000) + (group << 10 & 0x1000) - + (palette << 4 & 0x0380) + (group << 5 & 0x0040) - + (palette << 2 & 0x001c) + (group << 1 & 0x0002); + return pen_indirect(DIRECT_COLOUR + palette + (group * 256)); } void snes_ppu_device::set_current_vert(uint16_t value) @@ -1984,7 +1990,7 @@ uint8_t snes_ppu_device::read(uint32_t offset, uint8_t wrio_bit7) m_ppu2_open_bus |= cgram_read(m_cgram_address) & 0x7f; } - m_cgram_address = (m_cgram_address + 1) % (SNES_CGRAM_SIZE - 2); + m_cgram_address = (m_cgram_address + 1) & (SNES_CGRAM_SIZE - 1); return m_ppu2_open_bus; case OPHCT: /* Horizontal counter data by ext/soft latch */ if (m_read_ophct) @@ -2244,7 +2250,7 @@ void snes_ppu_device::write(uint32_t offset, uint8_t data) break; case CGDATA: /* Data for colour RAM */ cgram_write(m_cgram_address, data); - m_cgram_address = (m_cgram_address + 1) % (SNES_CGRAM_SIZE - 2); + m_cgram_address = (m_cgram_address + 1) & (SNES_CGRAM_SIZE - 1); break; case W12SEL: /* Window mask settings for BG1-2 */ if (data != PPU_REG(W12SEL)) @@ -2374,13 +2380,13 @@ void snes_ppu_device::write(uint32_t offset, uint8_t data) break; case COLDATA: /* Fixed colour data for fixed colour addition/subtraction */ { - /* Store it in the extra space we made in the CGRAM. It doesn't really go there, but it's as good a place as any. */ + /* Store it in the extra space we made in the palette entry. */ uint8_t r, g, b; /* Get existing value. */ - r = m_cgram[FIXED_COLOUR] & 0x1f; - g = (m_cgram[FIXED_COLOUR] & 0x3e0) >> 5; - b = (m_cgram[FIXED_COLOUR] & 0x7c00) >> 10; + r = pen_indirect(FIXED_COLOUR) & 0x1f; + g = (pen_indirect(FIXED_COLOUR) & 0x3e0) >> 5; + b = (pen_indirect(FIXED_COLOUR) & 0x7c00) >> 10; /* Set new value */ if (data & 0x20) r = data & 0x1f; @@ -2388,7 +2394,7 @@ void snes_ppu_device::write(uint32_t offset, uint8_t data) g = data & 0x1f; if (data & 0x80) b = data & 0x1f; - m_cgram[FIXED_COLOUR] = (r | (g << 5) | (b << 10)); + set_pen_indirect(FIXED_COLOUR, r | (g << 5) | (b << 10)); } break; case SETINI: /* Screen mode/video select */ m_interlace = (data & 0x01) ? 2 : 1; diff --git a/src/devices/video/snes_ppu.h b/src/devices/video/snes_ppu.h index 77c13b4dfca..f6ae1b09fa4 100644 --- a/src/devices/video/snes_ppu.h +++ b/src/devices/video/snes_ppu.h @@ -37,7 +37,8 @@ // ======================> snes_ppu_device class snes_ppu_device : public device_t, - public device_video_interface + public device_video_interface, + public device_palette_interface { public: // construction/destruction @@ -312,7 +313,15 @@ protected: virtual void device_start() override; virtual void device_reset() override; + // device_palette_interface overrides + // 256 word CG RAM data (0x000-0x0ff), 8 group of direct colours (0x100-0x8ff), Fixed color (0x900) + virtual uint32_t palette_entries() const override { return 0x100 + (0x100 * 8) + 1; } + virtual uint32_t palette_indirect_entries() const override { return 32 * 32 * 32; } // 15 bit BGR + private: + static constexpr uint16_t DIRECT_COLOUR = 0x100; // Position in palette entry for direct colour + static constexpr uint16_t FIXED_COLOUR = 0x100 + (0x100 * 8); // Position in palette entry for fixed colour + devcb_read16 m_openbus_cb; optional_ioport m_options; optional_ioport m_debug1; |