From 79c2e940c53eb164e69d910f8fcb21d11a9d3e55 Mon Sep 17 00:00:00 2001 From: r09 Date: Sun, 24 Dec 2017 14:35:06 +0100 Subject: [PATCH] fmtowns: fix horizontal wrap for bitmap layers (#2964) * fmtowns: fix horizontal wrap for bitmap layers * fmtowns: use lambda expressions to check for wrapping * return int instead of bool --- src/mame/video/fmtowns.cpp | 69 ++++++++++++++++++++++++++------------ 1 file changed, 47 insertions(+), 22 deletions(-) diff --git a/src/mame/video/fmtowns.cpp b/src/mame/video/fmtowns.cpp index a6d6e5bca5f..c436d0d3b3b 100644 --- a/src/mame/video/fmtowns.cpp +++ b/src/mame/video/fmtowns.cpp @@ -903,9 +903,9 @@ void towns_state::render_sprite_16(uint32_t poffset, uint16_t x, uint16_t y, boo { ystart = y; if (yhalfsize) - yend = y+16; - else yend = y+8; + else + yend = y+16; ydir = 1; } xstart &= 0x1ff; @@ -1033,11 +1033,18 @@ void towns_state::towns_crtc_draw_scan_layer_hicolour(bitmap_rgb32 &bitmap,const int hzoom = 1; int linesize; uint32_t scroll; + bool sprites_enabled = (m_video.towns_sprite_reg[1] & 0x80) >> 7; if(layer == 0) linesize = m_video.towns_crtc_reg[20] * 4; else linesize = m_video.towns_crtc_reg[24] * 4; + + // TODO: figure out how to wrap when there are sprites on layer 1 + auto wrap = [layer,sprites_enabled,linesize](int line, uint32_t off)->int + { + return ((layer == 0 || !sprites_enabled) && off >= (line * linesize) && off - (line * linesize) >= linesize); + }; if(m_video.towns_display_page_sel != 0) off = 0x20000; @@ -1084,7 +1091,11 @@ void towns_state::towns_crtc_draw_scan_layer_hicolour(bitmap_rgb32 &bitmap,const else off &= 0x7ffff; // 1 layer - colour = (m_towns_gfxvram[off+(layer*0x40000)+1] << 8) | m_towns_gfxvram[off+(layer*0x40000)]; + // TODO: figure out how to wrap when there are sprites on layer 1 + if ((layer == 0 || !(m_video.towns_sprite_reg[1] & 0x80)) && off >= (line * linesize) && off - (line * linesize) >= linesize) + colour = (m_towns_gfxvram[off+(layer*0x40000)-linesize+1] << 8) | m_towns_gfxvram[off+(layer*0x40000)-linesize]; + else + colour = (m_towns_gfxvram[off+(layer*0x40000)+1] << 8) | m_towns_gfxvram[off+(layer*0x40000)]; if(colour < 0x8000) { bitmap.pix32(scanline, x) = @@ -1104,7 +1115,7 @@ void towns_state::towns_crtc_draw_scan_layer_hicolour(bitmap_rgb32 &bitmap,const off &= 0x3ffff; // 2 layers else off &= 0x7ffff; // 1 layer - colour = (m_towns_gfxvram[off+(layer*0x40000)+1] << 8) | m_towns_gfxvram[off+(layer*0x40000)]; + colour = (m_towns_gfxvram[off+(layer*0x40000)-(wrap(line,off)*linesize)+1] << 8) | m_towns_gfxvram[off+(layer*0x40000)-(wrap(line,off)*linesize)]; if(colour < 0x8000) { bitmap.pix32(scanline, x) = @@ -1128,7 +1139,7 @@ void towns_state::towns_crtc_draw_scan_layer_hicolour(bitmap_rgb32 &bitmap,const off &= 0x3ffff; // 2 layers else off &= 0x7ffff; // 1 layer - colour = (m_towns_gfxvram[off+(layer*0x40000)+1] << 8) | m_towns_gfxvram[off+(layer*0x40000)]; + colour = (m_towns_gfxvram[off+(layer*0x40000)-(wrap(line,off)*linesize)+1] << 8) | m_towns_gfxvram[off+(layer*0x40000)-(wrap(line,off)*linesize)]; if(colour < 0x8000) { bitmap.pix32(scanline, x) = @@ -1156,7 +1167,7 @@ void towns_state::towns_crtc_draw_scan_layer_hicolour(bitmap_rgb32 &bitmap,const off &= 0x3ffff; // 2 layers else off &= 0x7ffff; // 1 layer - colour = (m_towns_gfxvram[off+(layer*0x40000)+1] << 8) | m_towns_gfxvram[off+(layer*0x40000)]; + colour = (m_towns_gfxvram[off+(layer*0x40000)-(wrap(line,off)*linesize)+1] << 8) | m_towns_gfxvram[off+(layer*0x40000)-(wrap(line,off)*linesize)]; if(colour < 0x8000) { bitmap.pix32(scanline, x) = @@ -1188,7 +1199,7 @@ void towns_state::towns_crtc_draw_scan_layer_hicolour(bitmap_rgb32 &bitmap,const off &= 0x3ffff; // 2 layers else off &= 0x7ffff; // 1 layer - colour = (m_towns_gfxvram[off+(layer*0x40000)+1] << 8) | m_towns_gfxvram[off+(layer*0x40000)]; + colour = (m_towns_gfxvram[off+(layer*0x40000)-(wrap(line,off)*linesize)+1] << 8) | m_towns_gfxvram[off+(layer*0x40000)-(wrap(line,off)*linesize)]; if(colour < 0x8000) { bitmap.pix32(scanline, x) = @@ -1225,6 +1236,7 @@ void towns_state::towns_crtc_draw_scan_layer_256(bitmap_rgb32 &bitmap,const rect int hzoom = 1; int linesize; uint32_t scroll; + bool sprites_enabled = (m_video.towns_sprite_reg[1] & 0x80) >> 7; if(m_video.towns_display_page_sel != 0) off = 0x20000; @@ -1237,6 +1249,12 @@ void towns_state::towns_crtc_draw_scan_layer_256(bitmap_rgb32 &bitmap,const rect else linesize = m_video.towns_crtc_reg[24] * 8; + // TODO: figure out how to wrap when there are sprites on layer 1 + auto wrap = [layer,sprites_enabled,linesize](int line, uint32_t off)->int + { + return ((layer == 0 || !sprites_enabled) && off >= (line * linesize) && off - (line * linesize) >= linesize); + }; + if(layer != 0) { if(!(m_video.towns_video_reg[0] & 0x10)) @@ -1274,7 +1292,7 @@ void towns_state::towns_crtc_draw_scan_layer_256(bitmap_rgb32 &bitmap,const rect off &= 0x3ffff; // 2 layers else off &= 0x7ffff; // 1 layer - colour = m_towns_gfxvram[off+(layer*0x40000)]; + colour = m_towns_gfxvram[off+(layer*0x40000)-(wrap(line,off)*linesize)]; if(colour != 0) { bitmap.pix32(scanline, x) = m_palette->pen(colour); @@ -1291,7 +1309,7 @@ void towns_state::towns_crtc_draw_scan_layer_256(bitmap_rgb32 &bitmap,const rect off &= 0x3ffff; // 2 layers else off &= 0x7ffff; // 1 layer - colour = m_towns_gfxvram[off+(layer*0x40000)+1]; + colour = m_towns_gfxvram[off+(layer*0x40000)-(wrap(line,off)*linesize)]; if(colour != 0) { bitmap.pix32(scanline, x) = m_palette->pen(colour); @@ -1309,7 +1327,7 @@ void towns_state::towns_crtc_draw_scan_layer_256(bitmap_rgb32 &bitmap,const rect off &= 0x3ffff; // 2 layers else off &= 0x7ffff; // 1 layer - colour = m_towns_gfxvram[off+(layer*0x40000)+1]; + colour = m_towns_gfxvram[off+(layer*0x40000)-(wrap(line,off)*linesize)]; if(colour != 0) { bitmap.pix32(scanline, x) = m_palette->pen(colour); @@ -1328,7 +1346,7 @@ void towns_state::towns_crtc_draw_scan_layer_256(bitmap_rgb32 &bitmap,const rect off &= 0x3ffff; // 2 layers else off &= 0x7ffff; // 1 layer - colour = m_towns_gfxvram[off+(layer*0x40000)+1]; + colour = m_towns_gfxvram[off+(layer*0x40000)-(wrap(line,off)*linesize)]; if(colour != 0) { bitmap.pix32(scanline, x) = m_palette->pen(colour); @@ -1348,7 +1366,7 @@ void towns_state::towns_crtc_draw_scan_layer_256(bitmap_rgb32 &bitmap,const rect off &= 0x3ffff; // 2 layers else off &= 0x7ffff; // 1 layer - colour = m_towns_gfxvram[off+(layer*0x40000)+1]; + colour = m_towns_gfxvram[off+(layer*0x40000)-(wrap(line,off)*linesize)]; if(colour != 0) { bitmap.pix32(scanline, x) = m_palette->pen(colour); @@ -1370,6 +1388,7 @@ void towns_state::towns_crtc_draw_scan_layer_16(bitmap_rgb32 &bitmap,const recta int hzoom = 1; int linesize; uint32_t scroll; + bool sprites_enabled = (m_video.towns_sprite_reg[1] & 0x80) >> 7; palette_device* pal = (layer == 0) ? m_palette16_0 : m_palette16_1; if(m_video.towns_display_page_sel != 0) @@ -1382,6 +1401,12 @@ void towns_state::towns_crtc_draw_scan_layer_16(bitmap_rgb32 &bitmap,const recta linesize = m_video.towns_crtc_reg[20] * 4; else linesize = m_video.towns_crtc_reg[24] * 4; + + // TODO: figure out how to wrap when there are sprites on layer 1 + auto wrap = [layer,sprites_enabled,linesize](int line, uint32_t off)->int + { + return ((layer == 0 || !sprites_enabled) && off >= (line * linesize) && off - (line * linesize) >= linesize); + }; if(layer != 0) { @@ -1420,12 +1445,12 @@ void towns_state::towns_crtc_draw_scan_layer_16(bitmap_rgb32 &bitmap,const recta off &= 0x3ffff; // 2 layers else off &= 0x7ffff; // 1 layer - colour = m_towns_gfxvram[off+(layer*0x40000)] >> 4; + colour = m_towns_gfxvram[off+(layer*0x40000)-(wrap(line,off)*linesize)] >> 4; if(colour != 0) { bitmap.pix32(scanline, x+1) = pal->pen(colour); } - colour = m_towns_gfxvram[off+(layer*0x40000)] & 0x0f; + colour = m_towns_gfxvram[off+(layer*0x40000)-(wrap(line,off)*linesize)] & 0x0f; if(colour != 0) { bitmap.pix32(scanline, x) = pal->pen(colour); @@ -1442,13 +1467,13 @@ void towns_state::towns_crtc_draw_scan_layer_16(bitmap_rgb32 &bitmap,const recta off &= 0x3ffff; // 2 layers else off &= 0x7ffff; // 1 layer - colour = m_towns_gfxvram[off+(layer*0x40000)] >> 4; + colour = m_towns_gfxvram[off+(layer*0x40000)-(wrap(line,off)*linesize)] >> 4; if(colour != 0) { bitmap.pix32(scanline, x+2) = pal->pen(colour); bitmap.pix32(scanline, x+3) = pal->pen(colour); } - colour = m_towns_gfxvram[off+(layer*0x40000)] & 0x0f; + colour = m_towns_gfxvram[off+(layer*0x40000)-(wrap(line,off)*linesize)] & 0x0f; if(colour != 0) { bitmap.pix32(scanline, x) = pal->pen(colour); @@ -1466,14 +1491,14 @@ void towns_state::towns_crtc_draw_scan_layer_16(bitmap_rgb32 &bitmap,const recta off &= 0x3ffff; // 2 layers else off &= 0x7ffff; // 1 layer - colour = m_towns_gfxvram[off+(layer*0x40000)] >> 4; + colour = m_towns_gfxvram[off+(layer*0x40000)-(wrap(line,off)*linesize)] >> 4; if(colour != 0) { bitmap.pix32(scanline, x+3) = pal->pen(colour); bitmap.pix32(scanline, x+4) = pal->pen(colour); bitmap.pix32(scanline, x+5) = pal->pen(colour); } - colour = m_towns_gfxvram[off+(layer*0x40000)] & 0x0f; + colour = m_towns_gfxvram[off+(layer*0x40000)-(wrap(line,off)*linesize)] & 0x0f; if(colour != 0) { bitmap.pix32(scanline, x) = pal->pen(colour); @@ -1492,7 +1517,7 @@ void towns_state::towns_crtc_draw_scan_layer_16(bitmap_rgb32 &bitmap,const recta off &= 0x3ffff; // 2 layers else off &= 0x7ffff; // 1 layer - colour = m_towns_gfxvram[off+(layer*0x40000)] >> 4; + colour = m_towns_gfxvram[off+(layer*0x40000)-(wrap(line,off)*linesize)] >> 4; if(colour != 0) { bitmap.pix32(scanline, x+4) = pal->pen(colour); @@ -1500,7 +1525,7 @@ void towns_state::towns_crtc_draw_scan_layer_16(bitmap_rgb32 &bitmap,const recta bitmap.pix32(scanline, x+6) = pal->pen(colour); bitmap.pix32(scanline, x+7) = pal->pen(colour); } - colour = m_towns_gfxvram[off+(layer*0x40000)] & 0x0f; + colour = m_towns_gfxvram[off+(layer*0x40000)-(wrap(line,off)*linesize)] & 0x0f; if(colour != 0) { bitmap.pix32(scanline, x) = pal->pen(colour); @@ -1520,7 +1545,7 @@ void towns_state::towns_crtc_draw_scan_layer_16(bitmap_rgb32 &bitmap,const recta off &= 0x3ffff; // 2 layers else off &= 0x7ffff; // 1 layer - colour = m_towns_gfxvram[off+(layer*0x40000)] >> 4; + colour = m_towns_gfxvram[off+(layer*0x40000)-(wrap(line,off)*linesize)] >> 4; if(colour != 0) { bitmap.pix32(scanline, x+5) = pal->pen(colour); @@ -1529,7 +1554,7 @@ void towns_state::towns_crtc_draw_scan_layer_16(bitmap_rgb32 &bitmap,const recta bitmap.pix32(scanline, x+8) = pal->pen(colour); bitmap.pix32(scanline, x+9) = pal->pen(colour); } - colour = m_towns_gfxvram[off+(layer*0x40000)] & 0x0f; + colour = m_towns_gfxvram[off+(layer*0x40000)-(wrap(line,off)*linesize)] & 0x0f; if(colour != 0) { bitmap.pix32(scanline, x) = pal->pen(colour);