1 // license:BSD-3-Clause
2 // copyright-holders:Uki
3 /*******************************************************************************
4 
5     Momoko 120% (c) 1986 Jaleco
6 
7     Video hardware driver by Uki
8 
9     02/Mar/2001 -
10 
11 *******************************************************************************/
12 
13 #include "emu.h"
14 #include "includes/momoko.h"
15 
16 
fg_scrollx_w(u8 data)17 void momoko_state::fg_scrollx_w(u8 data)
18 {
19 	m_fg_scrollx = data;
20 }
21 
fg_scrolly_w(u8 data)22 void momoko_state::fg_scrolly_w(u8 data)
23 {
24 	m_fg_scrolly = data;
25 }
26 
fg_select_w(u8 data)27 void momoko_state::fg_select_w(u8 data)
28 {
29 	m_fg_select = data & 0x0f;
30 	m_fg_mask = data & 0x10;
31 }
32 
text_scrolly_w(u8 data)33 void momoko_state::text_scrolly_w(u8 data)
34 {
35 	m_text_scrolly = data;
36 }
37 
text_mode_w(u8 data)38 void momoko_state::text_mode_w(u8 data)
39 {
40 	m_text_mode = data;
41 }
42 
bg_scrollx_w(offs_t offset,u8 data)43 void momoko_state::bg_scrollx_w(offs_t offset, u8 data)
44 {
45 	m_bg_scrollx[offset] = data;
46 }
47 
bg_scrolly_w(offs_t offset,u8 data)48 void momoko_state::bg_scrolly_w(offs_t offset, u8 data)
49 {
50 	m_bg_scrolly[offset] = data;
51 }
52 
bg_select_w(u8 data)53 void momoko_state::bg_select_w(u8 data)
54 {
55 	m_bg_select = data & 0x0f;
56 	m_bg_mask = data & 0x10;
57 }
58 
bg_priority_w(u8 data)59 void momoko_state::bg_priority_w(u8 data)
60 {
61 	m_bg_priority = data & 0x01;
62 }
63 
flipscreen_w(u8 data)64 void momoko_state::flipscreen_w(u8 data)
65 {
66 	m_flipscreen = data & 0x01;
67 }
68 
69 /****************************************************************************/
70 
draw_bg_pri(bitmap_ind16 & bitmap,int chr,int col,int flipx,int flipy,int x,int y,int pri)71 void momoko_state::draw_bg_pri(bitmap_ind16 &bitmap, int chr, int col, int flipx, int flipy, int x, int y, int pri)
72 {
73 	for (int sy = 0; sy < 8; sy++)
74 	{
75 		const u32 gfxadr = chr * 16 + sy * 2;
76 		for (int xx = 0; xx < 2; xx++)
77 		{
78 			u8 d0 = m_bg_gfx[gfxadr + xx * 4096];
79 			u8 d1 = m_bg_gfx[gfxadr + xx * 4096 + 1];
80 
81 			for (int sx = 0; sx < 4; sx++)
82 			{
83 				const u8 dot = (d0 & 0x08) | ((d0 & 0x80) >> 5) | ((d1 & 0x08) >> 2) | ((d1 & 0x80) >> 7);
84 				const int px = (flipx == 0) ? (sx + xx * 4 + x) : (7 - sx - xx * 4 + x);
85 				const int py = (flipy == 0) ? (sy + y) : (7 - sy + y);
86 
87 				if (dot >= pri)
88 					bitmap.pix(py, px) = col * 16 + dot + 256;
89 
90 				d0 <<= 1;
91 				d1 <<= 1;
92 			}
93 		}
94 	}
95 }
96 
97 /****************************************************************************/
98 
screen_update(screen_device & screen,bitmap_ind16 & bitmap,const rectangle & cliprect)99 u32 momoko_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
100 {
101 	int px, py, col;
102 
103 	const int flip = m_flipscreen ^ (m_io_fake->read() & 0x01);
104 
105 	/* draw BG layer */
106 	int dx = (7 - m_bg_scrollx[0]) & 7;
107 	int dy = (7 - m_bg_scrolly[0]) & 7;
108 	int rx = (m_bg_scrollx[0] + m_bg_scrollx[1] * 256) >> 3;
109 	int ry = (m_bg_scrolly[0] + m_bg_scrolly[1] * 256) >> 3;
110 
111 	if (m_bg_mask == 0)
112 	{
113 		for (int y = 0; y < 29; y++)
114 		{
115 			for (int x = 0; x < 32; x++)
116 			{
117 				const int radr = ((ry + y + 2) & 0x3ff) * 128 + ((rx + x) & 0x7f);
118 				u32 chr = m_bg_map[radr];
119 				col = m_bg_col_map[chr + m_bg_select * 512 + m_bg_priority * 256] & 0x0f;
120 				chr = chr + m_bg_select * 512;
121 
122 				if (flip == 0)
123 				{
124 					px = 8 * x + dx - 6;
125 					py = 8 * y + dy + 9;
126 				}
127 				else
128 				{
129 					px = 248 - (8 * x + dx - 8);
130 					py = 248 - (8 * y + dy + 9);
131 				}
132 
133 				m_gfxdecode->gfx(1)->opaque(bitmap,cliprect,
134 					chr,
135 					col,
136 					flip,flip,
137 					px,py);
138 			}
139 		}
140 	}
141 	else
142 	bitmap.fill(256, cliprect);
143 
144 
145 	/* draw sprites (momoko) */
146 	for (int offs = 0; offs < 9 * 4; offs +=4)
147 	{
148 		u32 chr = m_spriteram[offs + 1] | ((m_spriteram[offs + 2] & 0x60) << 3);
149 		chr = ((chr & 0x380) << 1) | (chr & 0x7f);
150 		col = m_spriteram[offs + 2] & 0x07;
151 		const int fx = ((m_spriteram[offs + 2] & 0x10) >> 4) ^ flip;
152 		const int fy = ((m_spriteram[offs + 2] & 0x08) >> 3) ^ flip; /* ??? */
153 		int x = m_spriteram[offs + 3];
154 		int y = m_spriteram[offs + 0];
155 
156 		if (flip == 0)
157 		{
158 			px = x;
159 			py = 239 - y;
160 		}
161 		else
162 		{
163 			px = 248 - x;
164 			py = y + 1;
165 		}
166 
167 		m_gfxdecode->gfx(3)->transpen(bitmap,cliprect,
168 			chr,
169 			col,
170 			!fx,fy,
171 			px,py,0);
172 	}
173 
174 
175 	/* draw BG layer */
176 	if (m_bg_mask == 0)
177 	{
178 		for (int y = 0; y < 29; y++)
179 		{
180 			for (int x = 0; x < 32; x++)
181 			{
182 				const int radr = ((ry + y + 2) & 0x3ff) * 128 + ((rx + x) & 0x7f);
183 				u32 chr = m_bg_map[radr];
184 				col = m_bg_col_map[chr + m_bg_select * 512 + m_bg_priority * 256];
185 				const u8 pri = (col & 0x10) >> 1;
186 
187 				if (flip == 0)
188 				{
189 					px = 8 * x + dx - 6;
190 					py = 8 * y + dy + 9;
191 					}
192 				else
193 				{
194 					px = 248 - (8 * x + dx - 8);
195 					py = 248 - (8 * y + dy + 9);
196 				}
197 				if (pri != 0)
198 				{
199 					col = col & 0x0f;
200 					chr = chr + m_bg_select * 512;
201 					draw_bg_pri(bitmap, chr, col, flip, flip, px, py, pri);
202 				}
203 			}
204 		}
205 	}
206 
207 
208 	/* draw sprites (others) */
209 	for (int offs = 9 * 4; offs < m_spriteram.bytes(); offs += 4)
210 	{
211 		u32 chr = m_spriteram[offs + 1] | ((m_spriteram[offs + 2] & 0x60) << 3);
212 		chr = ((chr & 0x380) << 1) | (chr & 0x7f);
213 		col = m_spriteram[offs + 2] & 0x07;
214 		const int fx = ((m_spriteram[offs + 2] & 0x10) >> 4) ^ flip;
215 		const int fy = ((m_spriteram[offs + 2] & 0x08) >> 3) ^ flip; /* ??? */
216 		int x = m_spriteram[offs + 3];
217 		int y = m_spriteram[offs + 0];
218 
219 		if (flip == 0)
220 		{
221 			px = x;
222 			py = 239 - y;
223 		}
224 		else
225 		{
226 			px = 248 - x;
227 			py = y + 1;
228 		}
229 		m_gfxdecode->gfx(3)->transpen(bitmap,cliprect,
230 			chr,
231 			col,
232 			!fx,fy,
233 			px,py,0);
234 	}
235 
236 
237 	/* draw text layer */
238 	for (int y = 16; y < 240; y++)
239 	{
240 		for (int x = 0; x < 32; x++)
241 		{
242 			int sy = y;
243 			if (m_text_mode == 0)
244 				col = m_proms[(sy >> 3) + 0x100] & 0x0f;
245 			else
246 			{
247 				if (m_proms[y] < 0x08)
248 					sy += m_text_scrolly;
249 				col = (m_proms[y] & 0x07) + 0x10;
250 			}
251 			dy = sy & 7;
252 			if (flip == 0)
253 			{
254 				px = x * 8;
255 				py = y;
256 			}
257 			else
258 			{
259 				px = 248 - x * 8;
260 				py = 255 - y;
261 			}
262 			m_gfxdecode->gfx(0)->transpen(bitmap,cliprect,
263 				m_videoram[(sy >> 3) * 32 + x] * 8 + dy,
264 				col,
265 				flip,0,
266 				px,py,0);
267 		}
268 	}
269 
270 
271 	/* draw FG layer */
272 	if (m_fg_mask == 0)
273 	{
274 		dx = (7 - m_fg_scrollx) & 7;
275 		dy = (7 - m_fg_scrolly) & 7;
276 		rx = m_fg_scrollx >> 3;
277 		ry = m_fg_scrolly >> 3;
278 
279 		for (int y = 0; y < 29; y++)
280 		{
281 			for (int x = 0; x < 32; x++)
282 			{
283 				const int radr = ((ry + y + 34) & 0x3f) * 0x20 + ((rx + x) & 0x1f) + (m_fg_select & 3) * 0x800;
284 				const u32 chr = m_fg_map[radr];
285 				if (flip == 0)
286 				{
287 					px = 8 * x + dx - 6;
288 					py = 8 * y + dy + 9;
289 				}
290 				else
291 				{
292 					px = 248 - (8 * x + dx - 8);
293 					py = 248 - (8 * y + dy + 9);
294 				}
295 				m_gfxdecode->gfx(2)->transpen(bitmap,cliprect,
296 					chr,
297 					0, /* color */
298 					flip,flip, /* flip */
299 					px,py,0);
300 			}
301 		}
302 	}
303 	return 0;
304 }
305