diff options
author | Ryan Holtz <ryan.holtz@arrowheadgs.com> | 2019-10-16 07:19:32 +0200 |
---|---|---|
committer | Ryan Holtz <ryan.holtz@arrowheadgs.com> | 2019-10-16 07:19:44 +0200 |
commit | 151f5fca2555be797ee45ab01bd226d8c71eae0e (patch) | |
tree | b16002b065d613743e1e5ac8d2f8fa7261f184e6 /src/devices/video | |
parent | 86fd3836d25971746fe4f99e45ea795a742b7918 (diff) |
-snes: The SNES only has 64kbytes of VRAM, not 128kbytes. Fixes graphics in Yoshi's Island, probably others. [Ryan Holtz, byuu]
Diffstat (limited to 'src/devices/video')
-rw-r--r-- | src/devices/video/snes_ppu.cpp | 111 |
1 files changed, 54 insertions, 57 deletions
diff --git a/src/devices/video/snes_ppu.cpp b/src/devices/video/snes_ppu.cpp index 4549c8292be..9e3912a84b0 100644 --- a/src/devices/video/snes_ppu.cpp +++ b/src/devices/video/snes_ppu.cpp @@ -75,6 +75,8 @@ #include "emu.h" #include "video/snes_ppu.h" +static bool s_debug_prints = false; + #define SNES_MAINSCREEN 0 #define SNES_SUBSCREEN 1 #define SNES_CLIP_NEVER 0 @@ -82,7 +84,7 @@ #define SNES_CLIP_OUT 2 #define SNES_CLIP_ALWAYS 3 -#define SNES_VRAM_SIZE 0x20000 /* 128kb of video ram */ +#define SNES_VRAM_SIZE 0x10000 /* 128kb of video ram */ #define SNES_CGRAM_SIZE 0x202 /* 256 16-bit colours + 1 tacked on 16-bit colour for fixed colour */ #define SNES_OAM_SIZE 0x440 /* 1088 bytes of Object Attribute Memory */ #define FIXED_COLOUR 256 /* Position in cgram for fixed colour */ @@ -753,13 +755,10 @@ inline uint32_t snes_ppu_device::get_tmap_addr( uint8_t layer, uint8_t tile_size inline void snes_ppu_device::update_line( uint16_t curline, uint8_t layer, uint8_t priority_b, uint8_t priority_a, uint8_t color_depth, uint8_t hires, uint8_t offset_per_tile, uint8_t direct_colors ) { - uint32_t tmap, tile, xoff, yoff, charaddr, addr; - uint16_t ii = 0, vflip, hflip, pal, pal_direct, tilemap; - uint8_t xscroll, priority; - int8_t yscroll; + if (s_debug_prints) printf("L:%d ", layer); + int tile_incr = 0; uint16_t opt_bit = (layer == SNES_BG1) ? 13 : (layer == SNES_BG2) ? 14 : 0; - uint8_t tile_size; /* variables depending on color_depth */ uint8_t color_planes = 2 << color_depth; /* below we cheat to simplify the code: 8BPP should have 0 pal offset, not 0x100 (but we take care of this by later using pal % FIXED_COLOUR) */ @@ -776,7 +775,10 @@ inline void snes_ppu_device::update_line( uint16_t curline, uint8_t layer, uint8 m_scanlines[SNES_SUBSCREEN].clip = m_layer[layer].sub_window_enabled; if (!m_scanlines[SNES_MAINSCREEN].enable && !m_scanlines[SNES_SUBSCREEN].enable) + { + if (s_debug_prints) printf("DA\n"); return; + } /* Handle Mosaic effects */ if (m_layer[layer].mosaic_enabled) @@ -786,18 +788,21 @@ inline void snes_ppu_device::update_line( uint16_t curline, uint8_t layer, uint8 curline /= 2; /* Find the size of the tiles (8x8 or 16x16) */ - tile_size = m_layer[layer].tile_size; + uint8_t tile_size = m_layer[layer].tile_size; /* Find scroll info */ - xoff = m_layer[layer].hoffs; - yoff = m_layer[layer].voffs; + uint32_t xoff = m_layer[layer].hoffs; + uint32_t yoff = m_layer[layer].voffs; - xscroll = xoff & ((1 << (3 + tile_size)) - 1); + uint8_t xscroll = xoff & ((1 << (3 + tile_size)) - 1); /* Jump to base map address */ - tmap = m_layer[layer].tilemap << 9; - charaddr = m_layer[layer].charmap << 13; + uint32_t tmap = m_layer[layer].tilemap << 9; + uint32_t charaddr = m_layer[layer].charmap << 13; + + if (s_debug_prints) printf("TS:%d XO:%d YO:%d XS:%d TM:%08x CA:%08x\n", tile_size, xoff, yoff, xscroll, tmap, charaddr); + uint16_t ii = 0; while (ii < 256 + (8 << tile_size)) { // determine the horizontal position (Bishojo Janshi Suchi Pai & Desert Figther have tile_size & hires == 1) @@ -840,7 +845,7 @@ inline void snes_ppu_device::update_line( uint16_t curline, uint8_t layer, uint8 } } - addr = get_tmap_addr(layer, tile_size, tmap, xpos, ypos); + uint32_t addr = get_tmap_addr(layer, tile_size, tmap, xpos, ypos); /* Tilemap format @@ -851,14 +856,14 @@ inline void snes_ppu_device::update_line( uint16_t curline, uint8_t layer, uint8 ppp = Tile palette. The number of entries in the palette depends on the Mode and the BG. cccccccccc = Tile number. */ - tilemap = m_vram[addr % SNES_VRAM_SIZE] | (m_vram[(addr + 1) % SNES_VRAM_SIZE] << 8); - vflip = BIT(tilemap, 15); - hflip = BIT(tilemap, 14); - priority = BIT(tilemap, 13) ? priority_a : priority_b; - pal_direct = ((tilemap & 0x1c00) >> 8); - tile = tilemap & 0x03ff; + uint16_t tilemap = m_vram[addr % SNES_VRAM_SIZE] | (m_vram[(addr + 1) % SNES_VRAM_SIZE] << 8); + uint16_t vflip = BIT(tilemap, 15); + uint16_t hflip = BIT(tilemap, 14); + uint8_t priority = BIT(tilemap, 13) ? priority_a : priority_b; + uint16_t pal_direct = ((tilemap & 0x1c00) >> 8); + uint32_t tile = tilemap & 0x03ff; - pal = ((pal_direct >> 2) << color_shift); + uint16_t pal = ((pal_direct >> 2) << color_shift); /* Mode 0 palettes are layer specific */ if (m_mode == 0) @@ -880,7 +885,7 @@ inline void snes_ppu_device::update_line( uint16_t curline, uint8_t layer, uint8 #endif /* SNES_LAYER_DEBUG */ /* figure out which line to draw */ - yscroll = ypos & ((8 << tile_size) - 1); + int8_t yscroll = ypos & ((8 << tile_size) - 1); if (tile_size) if (BIT(yscroll, 3) != vflip) @@ -1818,18 +1823,14 @@ inline void snes_ppu_device::draw_blend( uint16_t offset, uint16_t *colour, uint void snes_ppu_device::refresh_scanline( bitmap_rgb32 &bitmap, uint16_t curline ) { - uint16_t ii; - int x; - int fade; - struct SNES_SCANLINE *scanline1, *scanline2; - uint16_t c; - uint16_t prev_colour = 0; - int blurring = m_options.read_safe(0) & 0x01; + s_debug_prints = machine().input().code_pressed(KEYCODE_Q); + + bool blurring = m_options.read_safe(0) & 0x01; g_profiler.start(PROFILER_VIDEO); if (m_screen_disabled) /* screen is forced blank */ - for (x = 0; x < SNES_SCR_WIDTH * 2; x++) + for (int x = 0; x < SNES_SCR_WIDTH * 2; x++) bitmap.pix32(curline, x) = rgb_t::black(); else { @@ -1853,7 +1854,7 @@ void snes_ppu_device::refresh_scanline( bitmap_rgb32 &bitmap, uint16_t curline ) memset(m_scanlines[SNES_SUBSCREEN].blend_exception, 0, SNES_SCR_WIDTH); /* Draw back colour */ - for (ii = 0; ii < SNES_SCR_WIDTH; ii++) + for (uint16_t ii = 0; ii < SNES_SCR_WIDTH; ii++) { if (m_mode == 5 || m_mode == 6 || m_pseudo_hires) m_scanlines[SNES_SUBSCREEN].buffer[ii] = m_cgram[0]; @@ -1871,6 +1872,8 @@ void snes_ppu_device::refresh_scanline( bitmap_rgb32 &bitmap, uint16_t curline ) update_obsel(); + struct SNES_SCANLINE *scanline1 = &m_scanlines[SNES_MAINSCREEN]; + struct SNES_SCANLINE *scanline2 = &m_scanlines[SNES_SUBSCREEN]; #if SNES_LAYER_DEBUG if (dbg_video(curline)) { @@ -1884,35 +1887,29 @@ void snes_ppu_device::refresh_scanline( bitmap_rgb32 &bitmap, uint16_t curline ) scanline1 = &m_scanlines[SNES_SUBSCREEN]; scanline2 = &m_scanlines[SNES_MAINSCREEN]; } - else -#endif /* SNES_LAYER_DEBUG */ - { - scanline1 = &m_scanlines[SNES_MAINSCREEN]; - scanline2 = &m_scanlines[SNES_SUBSCREEN]; - } +#endif /* Draw the scanline to screen */ - fade = m_screen_brightness; + int fade = m_screen_brightness; + uint16_t prev_colour = 0; - for (x = 0; x < SNES_SCR_WIDTH; x++) + for (int x = 0; x < SNES_SCR_WIDTH; x++) { - int r, g, b, hires; - uint16_t tmp_col[2]; - hires = (m_mode != 5 && m_mode != 6 && !m_pseudo_hires) ? 0 : 1; + const bool hires = (m_mode != 5 && m_mode != 6 && !m_pseudo_hires) ? false : true; /* in hires, the first pixel (of 512) is subscreen pixel, then the first mainscreen pixel follows, and so on... */ if (!hires) { - c = scanline1->buffer[x]; + uint16_t c = scanline1->buffer[x]; /* perform color math if the layer wants it (except if it's an object > 192) */ if (!scanline1->blend_exception[x] && m_layer[scanline1->layer[x]].color_math) draw_blend(x, &c, m_prevent_color_math, m_clip_to_black, 0); - r = ((c & 0x1f) * fade) >> 4; - g = (((c & 0x3e0) >> 5) * fade) >> 4; - b = (((c & 0x7c00) >> 10) * fade) >> 4; + int r = ((c & 0x1f) * fade) >> 4; + int g = (((c & 0x3e0) >> 5) * fade) >> 4; + int b = (((c & 0x7c00) >> 10) * fade) >> 4; bitmap.pix32(curline, x * 2 + 0) = rgb_t(pal5bit(r), pal5bit(g), pal5bit(b)); bitmap.pix32(curline, x * 2 + 1) = rgb_t(pal5bit(r), pal5bit(g), pal5bit(b)); @@ -1920,13 +1917,13 @@ void snes_ppu_device::refresh_scanline( bitmap_rgb32 &bitmap, uint16_t curline ) else { /* prepare the pixel from main screen */ - c = scanline1->buffer[x]; + uint16_t c = scanline1->buffer[x]; /* perform color math if the layer wants it (except if it's an object > 192) */ if (!scanline1->blend_exception[x] && m_layer[scanline1->layer[x]].color_math) draw_blend(x, &c, m_prevent_color_math, m_clip_to_black, 0); - tmp_col[1] = c; + uint16_t tmp_col1 = c; /* prepare the pixel from sub screen */ c = scanline2->buffer[x]; @@ -1941,33 +1938,33 @@ void snes_ppu_device::refresh_scanline( bitmap_rgb32 &bitmap, uint16_t curline ) else if (x > 0 && !scanline1->blend_exception[x - 1] && m_layer[scanline1->layer[x - 1]].color_math) draw_blend(x, &c, m_prevent_color_math, m_clip_to_black, 1); - tmp_col[0] = c; + uint16_t tmp_col0 = c; /* average the first pixel if required, or draw it directly*/ if (blurring) - c = (prev_colour + tmp_col[0] - ((prev_colour ^ tmp_col[0]) & 0x0421)) >> 1; // Hack code to mimic TV pixel blurring + c = (prev_colour + tmp_col0 - ((prev_colour ^ tmp_col0) & 0x0421)) >> 1; // Hack code to mimic TV pixel blurring else - c = tmp_col[0]; + c = tmp_col0; - r = ((c & 0x1f) * fade) >> 4; - g = (((c & 0x3e0) >> 5) * fade) >> 4; - b = (((c & 0x7c00) >> 10) * fade) >> 4; + int r = ((c & 0x1f) * fade) >> 4; + int g = (((c & 0x3e0) >> 5) * fade) >> 4; + int b = (((c & 0x7c00) >> 10) * fade) >> 4; bitmap.pix32(curline, x * 2 + 0) = rgb_t(pal5bit(r), pal5bit(g), pal5bit(b)); - prev_colour = tmp_col[0]; + prev_colour = tmp_col0; /* average the second pixel if required, or draw it directly*/ if (blurring) - c = (prev_colour + tmp_col[1] - ((prev_colour ^ tmp_col[1]) & 0x0421)) >> 1; // Hack code to mimic TV pixel blurring + c = (prev_colour + tmp_col1 - ((prev_colour ^ tmp_col1) & 0x0421)) >> 1; // Hack code to mimic TV pixel blurring else - c = tmp_col[1]; + c = tmp_col1; r = ((c & 0x1f) * fade) >> 4; g = (((c & 0x3e0) >> 5) * fade) >> 4; b = (((c & 0x7c00) >> 10) * fade) >> 4; bitmap.pix32(curline, x * 2 + 1) = rgb_t(pal5bit(r), pal5bit(g), pal5bit(b)); - prev_colour = tmp_col[1]; + prev_colour = tmp_col1; } } } |