summaryrefslogtreecommitdiffstatshomepage
path: root/src/mame/video/elan_eu3a14vid.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/mame/video/elan_eu3a14vid.cpp')
-rw-r--r--src/mame/video/elan_eu3a14vid.cpp766
1 files changed, 766 insertions, 0 deletions
diff --git a/src/mame/video/elan_eu3a14vid.cpp b/src/mame/video/elan_eu3a14vid.cpp
new file mode 100644
index 00000000000..79b2f4a97d0
--- /dev/null
+++ b/src/mame/video/elan_eu3a14vid.cpp
@@ -0,0 +1,766 @@
+// license:BSD-3-Clause
+// copyright-holders:David Haywood
+
+#include "emu.h"
+#include "elan_eu3a14vid.h"
+
+DEFINE_DEVICE_TYPE(ELAN_EU3A14_VID, elan_eu3a14vid_device, "elan_eu3a14vid", "Elan EU3A14 Video")
+
+elan_eu3a14vid_device::elan_eu3a14vid_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
+ : elan_eu3a05commonvid_device(mconfig, ELAN_EU3A14_VID, tag, owner, clock),
+ m_cpu(*this, finder_base::DUMMY_TAG),
+ m_bank(*this, finder_base::DUMMY_TAG),
+ m_screen(*this, finder_base::DUMMY_TAG)
+{
+}
+
+void elan_eu3a14vid_device::device_start()
+{
+ elan_eu3a05commonvid_device::device_start();
+}
+
+void elan_eu3a14vid_device::device_reset()
+{
+ elan_eu3a05commonvid_device::device_reset();
+
+ m_spriteaddr = 0x14; // ?? rad_foot never writes, other games seem to use it to set sprite location
+}
+
+
+
+uint8_t elan_eu3a14vid_device::read_vram(int offset)
+{
+ address_space& cpuspace = m_cpu->space(AS_PROGRAM);
+ int realoffset = offset + 0x200;
+ if (realoffset < 0x4000)
+ {
+ return cpuspace.read_byte(realoffset);
+ }
+ else
+ return 0x00;
+}
+
+uint32_t elan_eu3a14vid_device::screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
+{
+ m_spriterambase = (m_spriteaddr * 0x200) - 0x200;
+
+ bitmap.fill(0, cliprect);
+ m_prioritybitmap.fill(0, cliprect);
+
+ draw_background(screen, bitmap, cliprect);
+
+ draw_sprites(screen, bitmap, cliprect);
+ return 0;
+}
+
+void elan_eu3a14vid_device::video_start()
+{
+ m_screen->register_screen_bitmap(m_prioritybitmap);
+}
+
+
+uint8_t elan_eu3a14vid_device::read_gfxdata(int offset, int x)
+{
+ address_space& fullbankspace = m_bank->space(AS_PROGRAM);
+ return fullbankspace.read_byte((offset+x) & 0x3fffff);
+}
+
+void elan_eu3a14vid_device::draw_background_tile(bitmap_ind16& bitmap, const rectangle& cliprect, int bpp, int tileno, int palette, int priority, int flipx, int flipy, int xpos, int ypos, int transpen, int size, int base, int drawfromram)
+{
+ int baseaddr = base * 256;
+
+ int xstride = 8;
+
+ if (bpp == 8) // 8bpp selection
+ {
+ if (size == 8)
+ {
+ xstride = size / 1; baseaddr += tileno * 64; // 8x8 8bpp
+ }
+ else
+ {
+ xstride = size / 1; baseaddr += tileno * 256; // 16x16 8bpp
+ }
+
+ palette &= 0x100; // only top bit valid, as there are only 2 palettes?
+ }
+ else if (bpp == 4) // 4bpp selection
+ {
+ if (size == 8)
+ {
+ xstride = size / 2; baseaddr += tileno * 32; // 8x8 4bpp
+ }
+ else
+ {
+ xstride = size / 2; baseaddr += tileno * 128; // 16x16 4bpp
+ }
+ }
+ else if (bpp == 2) // 2bpp?
+ {
+ xstride = size / 4; baseaddr += tileno * 64; // 16x16 2bpp
+ }
+ else
+ {
+ popmessage("draw_background_tile unsupported bpp %d\n", bpp);
+ return;
+ }
+
+
+ int count = 0;
+ for (int y = 0; y < size; y++)
+ {
+ int realy = ypos + y;
+ int xposwithscroll = 0;
+
+ if (!drawfromram)
+ {
+ xposwithscroll = xpos - get_xscroll_for_screenypos(realy);
+ }
+ else
+ {
+ xposwithscroll = xpos;
+ // RAM tile layer has no scrolling? (or we've never seen it used / enabled)
+ }
+
+ uint16_t* dst = &bitmap.pix16(ypos + y);
+ uint8_t* pridst = &m_prioritybitmap.pix8(ypos + y);
+
+ for (int x = 0; x < xstride; x++)
+ {
+ int pix;
+
+ if (drawfromram)
+ {
+ pix = read_vram((baseaddr + count) & 0x3fff);
+ }
+ else
+ {
+ address_space& fullbankspace = m_bank->space(AS_PROGRAM);
+ pix = fullbankspace.read_byte((baseaddr+count) & 0x3fffff);
+ }
+
+ if (realy >= cliprect.min_y && realy <= cliprect.max_y)
+ {
+ if (bpp == 8) // 8bpp
+ {
+ int realx = x + xposwithscroll;
+ if (realx >= cliprect.min_x && realx <= cliprect.max_x)
+ {
+ if (pix)
+ {
+ if (pridst[realx] <= priority)
+ {
+ dst[realx] = pix | palette;
+ pridst[realx] = priority;
+ }
+
+ }
+ }
+ }
+ else if (bpp == 7)
+ {
+ popmessage("draw_background_tile bpp == 7");
+ }
+ else if (bpp == 6)
+ {
+ popmessage("draw_background_tile bpp == 6");
+ }
+ else if (bpp == 5)
+ {
+ popmessage("draw_background_tile bpp == 5");
+ }
+ else if (bpp == 4) // 4bpp
+ {
+ int realx = (x * 2) + xposwithscroll;
+ if (realx >= cliprect.min_x && realx <= cliprect.max_x)
+ {
+ if (pix & 0xf0)
+ {
+ if (pridst[realx] <= priority)
+ {
+ dst[realx] = ((pix & 0xf0) >> 4) | palette;
+ pridst[realx] = priority;
+ }
+ }
+ }
+
+ realx++;
+
+ if (realx >= cliprect.min_x && realx <= cliprect.max_x)
+ {
+ if (pix & 0x0f)
+ {
+ if (pridst[realx] <= priority)
+ {
+ dst[realx] = (pix & 0x0f) | palette;
+ pridst[realx] = priority;
+ }
+ }
+ }
+ }
+ else if (bpp == 3)
+ {
+ popmessage("draw_background_tile bpp == 3");
+ }
+ else if (bpp == 2) // 2bpp (hnt3 ram text)
+ {
+ int realx = (x * 4) + xposwithscroll;
+ if (realx >= cliprect.min_x && realx <= cliprect.max_x)
+ {
+ if (pix & 0xc0)
+ {
+ if (pridst[realx] <= priority)
+ {
+ dst[realx] = ((pix & 0xc0) >> 6) | palette;
+ pridst[realx] = priority;
+ }
+ }
+ }
+
+ realx++;
+
+ if (realx >= cliprect.min_x && realx <= cliprect.max_x)
+ {
+ if (pix & 0x30)
+ {
+ if (pridst[realx] <= priority)
+ {
+ dst[realx] = ((pix & 0x30) >> 4) | palette;
+ pridst[realx] = priority;
+ }
+ }
+ }
+
+ realx++;
+
+ if (realx >= cliprect.min_x && realx <= cliprect.max_x)
+ {
+ if (pix & 0x0c)
+ {
+ if (pridst[realx] <= priority)
+ {
+ dst[realx] = ((pix & 0x0c) >> 2) | palette;
+ pridst[realx] = priority;
+ }
+ }
+ }
+
+ realx++;
+
+ if (realx >= cliprect.min_x && realx <= cliprect.max_x)
+ {
+ if (pix & 0x03)
+ {
+ if (pridst[realx] <= priority)
+ {
+ dst[realx] = ((pix & 0x03) >> 0) | palette;
+ pridst[realx] = priority;
+ }
+ }
+ }
+ }
+ else if (bpp == 1)
+ {
+ popmessage("draw_background_tile bpp == 1");
+ }
+ }
+ count++;
+ }
+ }
+}
+
+int elan_eu3a14vid_device::get_xscroll_for_screenypos(int ydraw)
+{
+ if ((ydraw < 0) || (ydraw >= 224))
+ return 0;
+
+ int xscroll = m_scrollregs[0] | (m_scrollregs[1] << 8);
+
+ if (m_rowscrollcfg[1] == 0x01) // GUESS! could be anything, but this bit is set in Huntin'3
+ {
+ int split0 = m_rowscrollregs[0] | (m_rowscrollregs[1] << 8);
+ int split1 = m_rowscrollregs[2] | (m_rowscrollregs[3] << 8);
+ int split2 = m_rowscrollregs[4] | (m_rowscrollregs[5] << 8);
+ int split3 = m_rowscrollregs[6] | (m_rowscrollregs[7] << 8);
+
+ if (ydraw < m_rowscrollsplit[0])
+ {
+ return xscroll;
+ }
+ else if (ydraw < m_rowscrollsplit[1])
+ {
+ return split0;
+ }
+ else if (ydraw < m_rowscrollsplit[2])
+ {
+ return split1;
+ }
+ else if (ydraw < m_rowscrollsplit[3])
+ {
+ return split2;
+ }
+ else if (ydraw < m_rowscrollsplit[4])
+ {
+ return split3;
+ }
+ else
+ {
+ return 0;
+ }
+ }
+ else
+ {
+ return xscroll;
+ }
+}
+
+
+void elan_eu3a14vid_device::draw_background_page(screen_device& screen, bitmap_ind16& bitmap, const rectangle& cliprect, int ramstart, int ramend, int xbase, int ybase, int size, int bpp, int base, int pagewidth, int pageheight, int bytespertile, int palettepri, int drawfromram)
+{
+
+ int palette = ((palettepri & 0xf0) >> 4) | ((palettepri & 0x08) << 1);
+ palette = palette << 4;
+ int priority = palettepri & 0x07;
+
+ int xdraw = xbase;
+ int ydraw = ybase;
+ int count = 0;
+
+ for (int i = ramstart; i < ramend; i += bytespertile)
+ {
+ int tile = 0;
+ int realpalette = palette;
+ int realpriority = priority;
+ int realbpp = bpp;
+
+ if (bytespertile == 2)
+ {
+ tile = read_vram(i + 0) | (read_vram(i + 1) << 8);
+ }
+ else if (bytespertile == 4) // rad_foot hidden test mode, rad_hnt3 "Target Range" (not yet correct)
+ {
+ tile = read_vram(i + 0) | (read_vram(i + 1) << 8);// | (read_vram(i + 2) << 16) | | (read_vram(i + 3) << 24);
+
+ // read_vram(i + 3) & 0x04 is set in both seen cases, maybe per-tile bpp?
+ // this would match up with this mode being inline replacements for m_tilecfg[1] (palettepri) and m_tilecfg[2] (bpp);
+
+ int newpalette = ((read_vram(i + 2) & 0xf0) >> 4) | ((read_vram(i + 2) & 0x08) << 1);
+ newpalette = newpalette << 4;
+ realpalette = newpalette;
+ realpriority = read_vram(i + 2) & 0x07;
+ realbpp = read_vram(i + 3) & 0x07;
+ if (realbpp == 0)
+ realbpp = 8;
+
+ }
+
+
+ draw_background_tile(bitmap, cliprect, realbpp, tile, realpalette, realpriority, 0, 0, xdraw, ydraw, 0, size, base, drawfromram);
+
+ xdraw += size;
+
+ count++;
+ if (((count % pagewidth) == 0))
+ {
+ xdraw -= size * pagewidth;
+ ydraw += size;
+ }
+ }
+}
+
+void elan_eu3a14vid_device::draw_background_ramlayer(screen_device& screen, bitmap_ind16& bitmap, const rectangle& cliprect)
+{
+ // this register use is questionable
+ if (m_ramtilecfg[0] & 0x80)
+ {
+ int rtm_size;;
+ int rtm_pagewidth;
+ int rtm_pageheight;
+ int rtm_yscroll;
+ int rtm_bpp;
+ int rtm_bytespertile = 2;
+ uint8_t palettepri = m_ramtilecfg[1];
+
+ rtm_yscroll = 0;
+
+ // this is the gfxbase in ram for all cases seen
+ int rtm_base = (0x2000 - 0x200) / 256;
+
+ // same as regular layer?
+ if (m_ramtilecfg[0] & 0x10)
+ {
+ rtm_size = 8;
+ rtm_pagewidth = 32;
+ rtm_pageheight = 28;
+ }
+ else
+ {
+ rtm_size = 16;
+ rtm_pagewidth = 32 / 2;
+ rtm_pageheight = 28 / 2;
+ }
+
+ rtm_bpp = m_ramtilecfg[2] & 0x07;
+ if (rtm_bpp == 0)
+ rtm_bpp = 8;
+
+ // this is in the same place even when the first tilemap is in 16x16 mode, probably a base register somewhere
+ int ramstart = m_tilerambase + 0x700;
+ int ramend = m_tilerambase + 0x700 + 0x700;
+
+ // hack for "Target Range" mode
+ if (m_ramtilecfg[5] == 0x06)
+ {
+ ramstart = 0x3980-0x200;
+ ramend = 0x3980-0x200 + 0x700;
+ }
+
+ // normal
+ draw_background_page(screen, bitmap, cliprect, ramstart, ramend, 0, 0 - rtm_yscroll, rtm_size, rtm_bpp, rtm_base, rtm_pagewidth, rtm_pageheight, rtm_bytespertile, palettepri, 1);
+ // wrap x
+ draw_background_page(screen, bitmap, cliprect, ramstart, ramend, (rtm_size * rtm_pagewidth), 0 - rtm_yscroll, rtm_size, rtm_bpp, rtm_base, rtm_pagewidth, rtm_pageheight, rtm_bytespertile, palettepri, 1);
+ // wrap y
+ draw_background_page(screen, bitmap, cliprect, ramstart, ramend, 0, (rtm_size * rtm_pageheight) + 0 - rtm_yscroll, rtm_size, rtm_bpp, rtm_base, rtm_pagewidth, rtm_pageheight, rtm_bytespertile, palettepri, 1);
+ // wrap x+y
+ draw_background_page(screen, bitmap, cliprect, ramstart, ramend, (rtm_size * rtm_pagewidth), (rtm_size * rtm_pageheight) + 0 - rtm_yscroll, rtm_size, rtm_bpp, rtm_base, rtm_pagewidth, rtm_pageheight, rtm_bytespertile, palettepri, 1);
+ }
+}
+
+
+void elan_eu3a14vid_device::draw_background(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
+{
+ int yscroll = m_scrollregs[2] | (m_scrollregs[3] << 8);
+
+ int base = (m_tilecfg[5] << 8) | m_tilecfg[4];
+ uint8_t palettepri = m_tilecfg[1];
+
+ int pagewidth = 1, pageheight = 1;
+ int bytespertile = 2;
+ int size;
+
+ // m_tilecfg[0] b-as ?-hh b = bytes per tile s = tilesize / page size? a = always set when tilemaps are in use - check? h = related to page positions, when set uses 2x2 pages? ? = used
+ // m_tilecfg[1] pppp x--? ? = used foot x = used, huntin3 summary (palette bank?) p = palette (used for different stages in huntin3 and the hidden test modes in others)
+ // m_tilecfg[2] ---- bbbb b = bpp mode (0 = 8bpp)
+ // m_tilecfg[3] ---- ---- (unused or more gfxbase?)
+ // m_tilecfg[4] gggg gggg gfxbase (lower bits)
+ // m_tilecfg[5] gggg gggg gfxbase (upper bits)
+
+ // ramtilecfg appears to be a similar format, except for the other layer with ram base tiles
+ // however 'a' in m_tilecfg[0] is NOT set
+ // also m_tilecfg[0] has 0x80 set, which would be 4 bytes per tile, but it isn't?
+ // the layer seems to be disabled by setting m_tilecfg[0] to 0?
+
+ if (m_tilecfg[0] & 0x10)
+ {
+ size = 8;
+ pagewidth = 32;
+ pageheight = 28;
+ }
+ else
+ {
+ size = 16;
+ pagewidth = 16;
+ pageheight = 14;
+ }
+
+ if (m_tilecfg[0] & 0x80)
+ {
+ bytespertile = 4;
+ }
+ else
+ {
+ bytespertile = 2;
+ }
+
+ int bpp = (m_tilecfg[2] & 0x07);
+ if (bpp == 0)
+ bpp = 8;
+
+ int ramstart = 0;
+ int ramend = 0;
+
+ int pagesize = pagewidth * pageheight * 2;
+
+ if (bytespertile == 4)
+ {
+ pagesize <<= 1; // shift because we need twice as much ram for this mode
+ }
+
+ if ((m_tilecfg[0] & 0x03) == 0x00) // tilemaps arranged as 2x2 pages?
+ {
+ ramstart = m_tilerambase + pagesize * 0;
+ ramend = m_tilerambase + pagesize * 1;
+
+ draw_background_page(screen, bitmap, cliprect, ramstart,ramend, 0, 0 - yscroll, size, bpp, base, pagewidth,pageheight, bytespertile, palettepri, 0); // normal
+ draw_background_page(screen, bitmap, cliprect, ramstart,ramend, (size * pagewidth * 2), 0 - yscroll, size, bpp, base, pagewidth,pageheight, bytespertile, palettepri, 0); // wrap x
+ draw_background_page(screen, bitmap, cliprect, ramstart,ramend, 0, (size * pageheight * 2) + 0 - yscroll, size, bpp, base, pagewidth,pageheight, bytespertile, palettepri, 0); // wrap y
+ draw_background_page(screen, bitmap, cliprect, ramstart,ramend, (size * pagewidth * 2), (size * pageheight * 2) + 0 - yscroll, size, bpp, base, pagewidth,pageheight, bytespertile, palettepri, 0); // wrap x+y
+
+ ramstart = m_tilerambase + pagesize * 1;
+ ramend = m_tilerambase + pagesize * 2;
+
+ draw_background_page(screen, bitmap, cliprect, ramstart,ramend, (size * pagewidth), 0 - yscroll, size, bpp, base, pagewidth,pageheight, bytespertile, palettepri, 0); // normal
+ draw_background_page(screen, bitmap, cliprect, ramstart,ramend, (size * pagewidth * 3), 0 - yscroll, size, bpp, base, pagewidth,pageheight, bytespertile, palettepri, 0); // wrap x
+ draw_background_page(screen, bitmap, cliprect, ramstart,ramend, (size * pagewidth), (size * pageheight * 2) + 0 - yscroll, size, bpp, base, pagewidth,pageheight, bytespertile, palettepri, 0); // wrap y
+ draw_background_page(screen, bitmap, cliprect, ramstart,ramend, (size * pagewidth * 3), (size * pageheight * 2) + 0 - yscroll, size, bpp, base, pagewidth,pageheight, bytespertile, palettepri, 0); // wrap x+y
+
+ ramstart = m_tilerambase + pagesize * 2;
+ ramend = m_tilerambase + pagesize * 3;
+
+ draw_background_page(screen, bitmap, cliprect, ramstart,ramend, 0, (size * pageheight) - yscroll, size, bpp, base, pagewidth,pageheight, bytespertile, palettepri, 0); // normal
+ draw_background_page(screen, bitmap, cliprect, ramstart,ramend, (size * pagewidth * 2), (size * pageheight) - yscroll, size, bpp, base, pagewidth,pageheight, bytespertile, palettepri, 0); // wrap x
+ draw_background_page(screen, bitmap, cliprect, ramstart,ramend, 0, (size * pageheight * 3) - yscroll, size, bpp, base, pagewidth,pageheight, bytespertile, palettepri, 0); // wrap y
+ draw_background_page(screen, bitmap, cliprect, ramstart,ramend, (size * pagewidth * 2), (size * pageheight * 3) - yscroll, size, bpp, base, pagewidth,pageheight, bytespertile, palettepri, 0); // wrap x+y
+
+ ramstart = m_tilerambase + pagesize * 3;
+ ramend = m_tilerambase + pagesize * 4;
+
+ draw_background_page(screen, bitmap, cliprect, ramstart,ramend, (size * pagewidth), (size * pageheight) - yscroll, size, bpp, base, pagewidth,pageheight, bytespertile, palettepri, 0); // normal
+ draw_background_page(screen, bitmap, cliprect, ramstart,ramend, (size * pagewidth * 3), (size * pageheight) - yscroll, size, bpp, base, pagewidth,pageheight, bytespertile, palettepri, 0); // wrap x
+ draw_background_page(screen, bitmap, cliprect, ramstart,ramend, (size * pagewidth), (size * pageheight * 3) - yscroll, size, bpp, base, pagewidth,pageheight, bytespertile, palettepri, 0);// wrap y
+ draw_background_page(screen, bitmap, cliprect, ramstart,ramend, (size * pagewidth * 3), (size * pageheight * 3) - yscroll, size, bpp, base, pagewidth,pageheight, bytespertile, palettepri, 0); // wrap x+y
+ }
+ else if ((m_tilecfg[0] & 0x03) == 0x03) // individual tilemaps? multiple layers?
+ {
+ // popmessage("m_tilecfg[0] & 0x03 multiple layers config %04x", base);
+ ramstart = m_tilerambase + pagesize * 0;
+ ramend = m_tilerambase + pagesize * 1;
+
+ // normal
+ draw_background_page(screen, bitmap, cliprect, ramstart, ramend, 0, 0 - yscroll, size, bpp, base, pagewidth,pageheight, bytespertile, palettepri, 0);
+ // wrap x
+ draw_background_page(screen, bitmap, cliprect, ramstart, ramend, (size * pagewidth), 0 - yscroll, size, bpp, base, pagewidth,pageheight, bytespertile, palettepri, 0);
+ // wrap y
+ draw_background_page(screen, bitmap, cliprect, ramstart, ramend, 0, (size * pageheight) + 0 - yscroll, size, bpp, base, pagewidth,pageheight, bytespertile, palettepri, 0);
+ // wrap x+y
+ draw_background_page(screen, bitmap, cliprect, ramstart, ramend, (size * pagewidth), (size * pageheight) + 0 - yscroll, size, bpp, base, pagewidth,pageheight, bytespertile, palettepri, 0);
+
+ // RAM based tile layer
+ draw_background_ramlayer(screen, bitmap, cliprect);
+ }
+ else
+ {
+ popmessage("m_tilecfg[0] & 0x03 unknown config");
+ }
+
+}
+
+void elan_eu3a14vid_device::draw_sprite_pix(const rectangle& cliprect, uint16_t* dst, uint8_t* pridst, int realx, int priority, uint8_t pix, uint8_t mask, uint8_t shift, int palette)
+{
+ if (realx >= cliprect.min_x && realx <= cliprect.max_x)
+ {
+ if (pridst[realx] <= priority)
+ {
+ if (pix & mask)
+ {
+ dst[realx] = ((pix & mask) >> shift) | palette;
+ pridst[realx] = priority;
+ }
+ }
+ }
+}
+
+void elan_eu3a14vid_device::draw_sprite_line(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect, int offset, int line, int palette, int flipx, int priority, int xpos, int ypos, int bpp)
+{
+ offset = offset * 2;
+
+ int bppdiv = 0;
+
+ switch (bpp)
+ {
+ default:
+ case 0x8:
+ case 0x7:
+ case 0x6:
+ case 0x5:
+ offset += line * 8;
+ bppdiv = 1;
+ break;
+
+ case 0x4:
+ case 0x3:
+ offset += line * 4;
+ bppdiv = 2;
+ break;
+
+ case 0x2:
+ offset += line * 2;
+ bppdiv = 4;
+ break;
+
+ case 0x1:
+ offset += line * 1;
+ bppdiv = 8;
+ break;
+ }
+
+
+ if (ypos >= cliprect.min_y && ypos <= cliprect.max_y)
+ {
+ uint16_t* dst = &bitmap.pix16(ypos);
+ uint8_t* pridst = &m_prioritybitmap.pix8(ypos);
+
+ int count = 0;
+ for (int x = 0; x < 8/bppdiv;x++)
+ {
+ if (bpp == 8)
+ {
+ int pix,mask,shift;
+ if (flipx) { pix = read_gfxdata(offset, 7 - count); } else { pix = read_gfxdata(offset, count); }
+ int realx = xpos + x * 1;
+ if (flipx) { mask = 0xff; shift = 0; } else { mask = 0xff; shift = 0; }
+ draw_sprite_pix(cliprect, dst, pridst, realx, priority, pix, mask, shift, palette);
+ }
+ else if (bpp == 7)
+ {
+ int pix,mask,shift;
+ if (flipx) { pix = read_gfxdata(offset, 7 - count); } else { pix = read_gfxdata(offset, count); }
+ int realx = xpos + x * 1;
+ // stride doesn't change, data isn't packed, just don't use top bit
+ if (flipx) { mask = 0x7f; shift = 0; } else { mask = 0x7f; shift = 0; }
+ draw_sprite_pix(cliprect, dst, pridst, realx, priority, pix, mask, shift, palette);
+ }
+ else if (bpp == 6)
+ {
+ popmessage("6bpp sprite\n");
+ }
+ else if (bpp == 5)
+ {
+ popmessage("5bpp sprite\n");
+ }
+ else if (bpp == 4)
+ {
+ int pix,mask,shift;
+ if (flipx) { pix = read_gfxdata(offset, 3 - count); } else { pix = read_gfxdata(offset, count); }
+ int realx = xpos + x * 2;
+ if (flipx) { mask = 0x0f; shift = 0; } else { mask = 0xf0; shift = 4; }
+ draw_sprite_pix(cliprect, dst, pridst, realx, priority, pix, mask, shift, palette);
+ realx++;
+ if (flipx) { mask = 0xf0; shift = 4; } else { mask = 0x0f; shift = 0; }
+ draw_sprite_pix(cliprect, dst, pridst, realx, priority, pix, mask, shift, palette);
+ }
+ else if (bpp == 3)
+ {
+ popmessage("3bpp sprite\n");
+ }
+ else if (bpp == 2)
+ {
+ int pix,mask,shift;
+ if (flipx) { pix = read_gfxdata(offset, 1 - count); } else { pix = read_gfxdata(offset, count); }
+ int realx = xpos + x * 4;
+ if (flipx) { mask = 0x03; shift = 0; } else { mask = 0xc0; shift = 6; }
+ draw_sprite_pix(cliprect, dst, pridst, realx, priority, pix, mask, shift, palette);
+ realx++;
+ if (flipx) { mask = 0x0c; shift = 2; } else { mask = 0x30; shift = 4; }
+ draw_sprite_pix(cliprect, dst, pridst, realx, priority, pix, mask, shift, palette);
+ realx++;
+ if (flipx) { mask = 0x30; shift = 4; } else { mask = 0x0c; shift = 2; }
+ draw_sprite_pix(cliprect, dst, pridst, realx, priority, pix, mask, shift, palette);
+ realx++;
+ if (flipx) { mask = 0xc0; shift = 6; } else { mask = 0x03; shift = 0; }
+ draw_sprite_pix(cliprect, dst, pridst, realx, priority, pix, mask, shift, palette);
+ }
+ else if (bpp == 1)
+ {
+ popmessage("1bpp sprite\n");
+ }
+
+ count++;
+ }
+ }
+
+}
+
+
+void elan_eu3a14vid_device::draw_sprites(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
+{
+ // first 4 sprite entries seem to be garbage sprites, so we start at 0x20
+ // likely we're just interpreting them wrong and they're used for blanking things or clipping?
+ for (int i = m_spriterambase; i < m_spriterambase + 0x800; i += 8)
+ {
+ /*
+ +0 e-ff hhww flip yx, enable, height, width
+ +1 yyyy yyyy ypos
+ +2 xxxx xxxx xpos
+ +3 pppp Pzzz p = palette, P = upper palette bank, z = priority
+ +4 tttt tttt tile bits
+ +5 tttt tttt
+ +6 --TT TPPP TTT = tile bank PPP = bpp select (+more?)
+ +7 ---- ----
+
+ */
+
+ int attr = read_vram(i + 0);
+ int y = read_vram(i + 1);
+ int x = read_vram(i + 2);
+ int palettepri = read_vram(i + 3);
+
+ int h = attr & 0x0c;
+ int w = attr & 0x03;
+ int flipx = (attr & 0x10) >> 4;
+ int flipy = (attr & 0x20) >> 5;
+
+ int height = 0;
+ int width = 0;
+
+ int pri = palettepri & 0x07;
+
+ int palette = ((palettepri & 0xf0) >> 4) | ((palettepri & 0x08) << 1);
+ palette = palette << 4;
+
+ switch (h)
+ {
+ case 0x0:height = 2; break;
+ case 0x4:height = 4; break;
+ case 0x8:height = 8; break;
+ case 0xc:height = 16; break;
+ }
+
+ switch (w)
+ {
+ case 0x0:width = 1; break;
+ case 0x1:width = 2; break;
+ case 0x2:width = 4; break;
+ case 0x3:width = 8; break;
+ }
+
+ y -= ((height * 2) - 4);
+
+ x -= ((width * 4) - 4);
+
+ height *= 4;
+
+ x -= 6;
+ y -= 4;
+
+ int offset = ((read_vram(i + 5) << 8) + (read_vram(i + 4) << 0));
+ int extra = read_vram(i + 6);
+
+ int spritebase = (m_spritebase[1] << 8) | m_spritebase[0];
+
+ offset += (extra & 0xf8) << 13;
+ offset += spritebase << 7;
+
+ int bpp = extra & 0x07;
+ if (bpp == 0)
+ bpp = 8;
+
+ if (attr & 0x80)
+ {
+ int count = 0;
+ for (int yy = 0; yy < height; yy++)
+ {
+ int yoff = flipy ? height-1-yy : yy;
+
+ for (int xx = 0; xx < width; xx++)
+ {
+ int xoff = flipx ? (((width - 1) * 8) - (xx * 8)) : (xx * 8);
+
+ draw_sprite_line(screen, bitmap, cliprect, offset, count, palette, flipx, pri, x + xoff, y + yoff, bpp);
+ count++;
+ }
+ }
+ }
+ }
+}
+