1 // license:BSD-3-Clause
2 // copyright-holders:David Haywood
3 // remaining gfx glitches
4 
5 // layer priority register not fully understood
6 
7 #include "emu.h"
8 #include "includes/drgnmst.h"
9 
10 
drgnmst_IIIIRRRRGGGGBBBB(uint32_t raw)11 rgb_t drgnmst_base_state::drgnmst_IIIIRRRRGGGGBBBB(uint32_t raw)
12 {
13 	int const bright = 0x5 + ((raw >> 12) & 0xf);    // TODO : verify brightness value from real pcb
14 	int r = (pal4bit((raw >> 8) & 0x0f) * bright) / 0x14;
15 	int g = (pal4bit((raw >> 4) & 0x0f) * bright) / 0x14;
16 	int b = (pal4bit((raw >> 0) & 0x0f) * bright) / 0x14;
17 
18 	if (r < 0) r = 0;
19 	if (r > 0xff) r = 0xff;
20 	if (g < 0) g = 0;
21 	if (g > 0xff) g = 0xff;
22 	if (b < 0) b = 0;
23 	if (b > 0xff) b = 0xff;
24 
25 	return rgb_t(r, g, b);
26 }
27 
TILE_GET_INFO_MEMBER(drgnmst_base_state::get_fg_tile_info)28 TILE_GET_INFO_MEMBER(drgnmst_base_state::get_fg_tile_info)
29 {
30 	// 8x8 tile layer
31 	int tileno, colour, flipyx;
32 	tileno = m_fg_videoram[tile_index * 2] & 0xfff;
33 	colour = m_fg_videoram[tile_index * 2 + 1] & 0x1f;
34 	flipyx = (m_fg_videoram[tile_index * 2 + 1] & 0x60)>>5;
35 
36 	if ((m_fg_videoram[tile_index * 2] & 0x4000))
37 		tileno |= 0x10000;
38 
39 	if ((m_fg_videoram[tile_index * 2] & 0x8000))
40 		tileno |= 0x8000;
41 
42 	tileno ^= 0x18000;
43 
44 //  tileno |= (BIT(tile_index, 5)) << 15; // 8x8 tile bank seems like cps1 (not on mastfury at least)
45 	tileinfo.set(1, tileno, colour, TILE_FLIPYX(flipyx));
46 }
47 
fg_videoram_w(offs_t offset,uint16_t data,uint16_t mem_mask)48 void drgnmst_base_state::fg_videoram_w(offs_t offset, uint16_t data, uint16_t mem_mask)
49 {
50 	COMBINE_DATA(&m_fg_videoram[offset]);
51 	m_fg_tilemap->mark_tile_dirty(offset / 2);
52 }
53 
TILE_GET_INFO_MEMBER(drgnmst_base_state::get_bg_tile_info)54 TILE_GET_INFO_MEMBER(drgnmst_base_state::get_bg_tile_info)
55 {
56 	// 32x32 tile layer
57 	int tileno, colour, flipyx;
58 	tileno = (m_bg_videoram[tile_index * 2] & 0x3ff) + 0xc00;
59 	colour = m_bg_videoram[tile_index * 2 + 1] & 0x1f;
60 	flipyx = (m_bg_videoram[tile_index * 2 + 1] & 0x60) >> 5;
61 
62 	if ((m_bg_videoram[tile_index * 2] & 0x1000))
63 		tileno |= 0x1000;
64 
65 	tileno ^= 0x1000;
66 
67 	tileinfo.set(3, tileno, colour, TILE_FLIPYX(flipyx));
68 }
69 
bg_videoram_w(offs_t offset,uint16_t data,uint16_t mem_mask)70 void drgnmst_base_state::bg_videoram_w(offs_t offset, uint16_t data, uint16_t mem_mask)
71 {
72 	COMBINE_DATA(&m_bg_videoram[offset]);
73 	m_bg_tilemap->mark_tile_dirty(offset / 2);
74 }
75 
TILE_GET_INFO_MEMBER(drgnmst_base_state::get_md_tile_info)76 TILE_GET_INFO_MEMBER(drgnmst_base_state::get_md_tile_info)
77 {
78 	// 16x16 tile layer
79 	int tileno, colour, flipyx;
80 	tileno = (m_md_videoram[tile_index * 2] & 0x3fff) - 0x2000;
81 	colour = m_md_videoram[tile_index * 2 + 1] & 0x1f;
82 	flipyx = (m_md_videoram[tile_index * 2 + 1] & 0x60) >> 5;
83 
84 	if ((m_md_videoram[tile_index * 2] & 0x4000))
85 		tileno |= 0x4000;
86 
87 	tileno ^= 0x4000;
88 
89 	tileinfo.set(2, tileno, colour, TILE_FLIPYX(flipyx));
90 }
91 
md_videoram_w(offs_t offset,uint16_t data,uint16_t mem_mask)92 void drgnmst_base_state::md_videoram_w(offs_t offset, uint16_t data, uint16_t mem_mask)
93 {
94 	COMBINE_DATA(&m_md_videoram[offset]);
95 	m_md_tilemap->mark_tile_dirty(offset / 2);
96 }
97 
draw_sprites(bitmap_ind16 & bitmap,const rectangle & cliprect)98 void drgnmst_base_state::draw_sprites( bitmap_ind16 &bitmap,const rectangle &cliprect )
99 {
100 	gfx_element *gfx = m_gfxdecode->gfx(0);
101 	uint16_t *source = m_spriteram;
102 	uint16_t *finish = source + 0x800 / 2;
103 
104 	while (source < finish)
105 	{
106 		int xpos, ypos, number, flipx, flipy, wide, high;
107 		int x, y;
108 		int incx, incy;
109 		int colr;
110 
111 		number = source[2];
112 		xpos = source[0];
113 		ypos = source[1];
114 		flipx = source[3] & 0x0020;
115 		flipy = source[3] & 0x0040;
116 		wide = (source[3] & 0x0f00) >> 8;
117 		high = (source[3] & 0xf000) >> 12;
118 		colr = (source[3] & 0x001f);
119 
120 		if ((source[3] & 0xff00) == 0xff00) break;
121 
122 
123 		if (!flipx) { incx = 16;} else { incx = -16; xpos += 16 * wide; }
124 		if (!flipy) { incy = 16;} else { incy = -16; ypos += 16 * high; }
125 
126 
127 		for (y = 0; y <= high; y++)
128 		{
129 			for (x = 0; x <= wide; x++)
130 			{
131 				int realx, realy, realnumber;
132 
133 				realx = xpos + incx * x;
134 				realy = ypos + incy * y;
135 				realnumber = number + x + y * 16;
136 
137 				gfx->transpen(bitmap,cliprect, realnumber, colr, flipx, flipy, realx, realy, 15);
138 			}
139 		}
140 		source += 4;
141 	}
142 }
143 
144 
TILEMAP_MAPPER_MEMBER(drgnmst_base_state::fg_tilemap_scan_cols)145 TILEMAP_MAPPER_MEMBER(drgnmst_base_state::fg_tilemap_scan_cols)
146 {
147 	return ((col & 0x3f) << 5) | (row & 0x1f) | ((row & 0x20) << 6);
148 }
149 
TILEMAP_MAPPER_MEMBER(drgnmst_base_state::md_tilemap_scan_cols)150 TILEMAP_MAPPER_MEMBER(drgnmst_base_state::md_tilemap_scan_cols)
151 {
152 	return ((col & 0x3f) << 4) | (row & 0x0f) | ((row & 0x30) << 6);
153 }
154 
TILEMAP_MAPPER_MEMBER(drgnmst_base_state::bg_tilemap_scan_cols)155 TILEMAP_MAPPER_MEMBER(drgnmst_base_state::bg_tilemap_scan_cols)
156 {
157 	return ((col & 0x3f) << 3) | (row & 0x07) | ((row & 0x38) << 6);
158 }
159 
video_start()160 void drgnmst_base_state::video_start()
161 {
162 	m_fg_tilemap = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(drgnmst_base_state::get_fg_tile_info)), tilemap_mapper_delegate(*this, FUNC(drgnmst_base_state::fg_tilemap_scan_cols)), 8, 8, 64,64);
163 	m_fg_tilemap->set_transparent_pen(15);
164 
165 	m_md_tilemap = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(drgnmst_base_state::get_md_tile_info)), tilemap_mapper_delegate(*this, FUNC(drgnmst_base_state::md_tilemap_scan_cols)), 16, 16, 64,64);
166 	m_md_tilemap->set_transparent_pen(15);
167 
168 	m_bg_tilemap = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(drgnmst_base_state::get_bg_tile_info)), tilemap_mapper_delegate(*this, FUNC(drgnmst_base_state::bg_tilemap_scan_cols)), 32, 32, 64,64);
169 	m_bg_tilemap->set_transparent_pen(15);
170 
171 	// do the other tilemaps have rowscroll too? probably not ..
172 	m_md_tilemap->set_scroll_rows(1024);
173 }
174 
video_start()175 void drgnmst_ym_state::video_start()
176 {
177 	drgnmst_base_state::video_start();
178 	m_alt_scrolling = true;
179 }
180 
screen_update(screen_device & screen,bitmap_ind16 & bitmap,const rectangle & cliprect)181 uint32_t drgnmst_base_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
182 {
183 	m_fg_tilemap->set_scrollx(0, m_vidregs[0x6] - 18); // verify (test mode colour test needs it)
184 	m_fg_tilemap->set_scrolly(0, m_vidregs[0x7]); // verify
185 
186 	int rowscroll_bank = (m_vidregs[4] & 0x30) >> 4;
187 
188 	if (!m_alt_scrolling)
189 	{
190 		m_bg_tilemap->set_scrollx(0, m_vidregs[0xa] - 18); // verify
191 		m_bg_tilemap->set_scrolly(0, m_vidregs[0xb]); // verify
192 
193 	//  m_md_tilemap->set_scrollx(0, m_vidregs[0x8] - 16); // rowscrolled
194 		m_md_tilemap->set_scrolly(0, m_vidregs[0x9]); // verify
195 
196 		for (int y = 0; y < 1024; y++)
197 			m_md_tilemap->set_scrollx(y, m_vidregs[0x8] - 16 + m_rowscrollram[y + 0x800 * rowscroll_bank]);
198 
199 		m_bg_tilemap->set_scrollx(0, m_vidregs[0xa] - 18); // verify
200 		m_bg_tilemap->set_scrolly(0, m_vidregs[0xb]); // verify
201 	}
202 	else
203 	{
204 	//  m_md_tilemap->set_scrollx(0, m_vidregs[0x9] - 16); // rowscrolled
205 		m_md_tilemap->set_scrolly(0, m_vidregs[0x8]); // verify
206 
207 		for (int y = 0; y < 1024; y++)
208 			m_md_tilemap->set_scrollx(y, m_vidregs[0x9] - 16 + m_rowscrollram[y + 0x800 * rowscroll_bank]);
209 
210 		m_bg_tilemap->set_scrollx(0, m_vidregs[0xa] - 18); // verify
211 		m_bg_tilemap->set_scrolly(0, m_vidregs[0xb] -0x400); // verify
212 
213 	}
214 
215 
216 	// todo: figure out which bits relate to the order
217 	switch (m_vidregs2[0])
218 	{
219 		case 0x2451: // fg unsure
220 		case 0x2d9a: // fg unsure
221 		case 0x2440: // all ok
222 		case 0x245a: // fg unsure, title screen
223 			m_fg_tilemap->draw(screen, bitmap, cliprect, TILEMAP_DRAW_OPAQUE, 0);
224 			m_md_tilemap->draw(screen, bitmap, cliprect, 0, 0);
225 			m_bg_tilemap->draw(screen, bitmap, cliprect, 0, 0);
226 			break;
227 		case 0x23c0: // all ok
228 			m_bg_tilemap->draw(screen, bitmap, cliprect, TILEMAP_DRAW_OPAQUE, 0);
229 			m_fg_tilemap->draw(screen, bitmap, cliprect, 0, 0);
230 			m_md_tilemap->draw(screen, bitmap, cliprect, 0, 0);
231 			break;
232 		case 0x38da: // fg unsure
233 		case 0x215a: // fg unsure
234 		case 0x2140: // all ok
235 			m_fg_tilemap->draw(screen, bitmap, cliprect, TILEMAP_DRAW_OPAQUE, 0);
236 			m_bg_tilemap->draw(screen, bitmap, cliprect, 0, 0);
237 			m_md_tilemap->draw(screen, bitmap, cliprect, 0, 0);
238 			break;
239 		case 0x2d80: // all ok
240 			m_md_tilemap->draw(screen, bitmap, cliprect, TILEMAP_DRAW_OPAQUE, 0);
241 			m_bg_tilemap->draw(screen, bitmap, cliprect, 0, 0);
242 			m_fg_tilemap->draw(screen, bitmap, cliprect, 0, 0);
243 			break;
244 		default:
245 			m_bg_tilemap->draw(screen, bitmap, cliprect, TILEMAP_DRAW_OPAQUE, 0);
246 			m_fg_tilemap->draw(screen, bitmap, cliprect, 0, 0);
247 			m_md_tilemap->draw(screen, bitmap, cliprect, 0, 0);
248 			logerror ("unknown video priority regs %04x\n", m_vidregs2[0]);
249 
250 	}
251 
252 	draw_sprites(bitmap,cliprect);
253 
254 //  popmessage ("x %04x x %04x x %04x x %04x x %04x", m_vidregs2[0], m_vidregs[12], m_vidregs[13], m_vidregs[14], m_vidregs[15]);
255 
256 	//popmessage ("x objbase: %04x scr0base %04x scr1base %04x scr2base %04x otherbase %04x palbase %04x",m_vidregs[0],m_vidregs[1],m_vidregs[2],m_vidregs[3],m_vidregs[4],m_vidregs[5]);
257 	//popmessage ("x fgx: %04x fgy: %04x 16x: %04x 16y: %04x 32x: %04x 32y: %04x",m_vidregs[0x6],m_vidregs[0x7],m_vidregs[0x8],m_vidregs[0x9],m_vidregs[0xa],m_vidregs[0xb]);
258 
259 	return 0;
260 }
261 
262