1 /******************************************************************************
2 
3 	Video Hardware for Nichibutsu Mahjong series.
4 
5 	Driver by Takahiro Nogi <nogi@kt.rim.or.jp> 1999/11/05 -
6 
7 ******************************************************************************/
8 
9 #include "driver.h"
10 #include "vidhrdw/generic.h"
11 #include "nb1413m3.h"
12 
13 
14 static int gionbana_scrolly1, gionbana_scrolly2;
15 static int gionbana_drawx, gionbana_drawy;
16 static int gionbana_sizex, gionbana_sizey;
17 static int gionbana_radrx, gionbana_radry;
18 static int gionbana_vram;
19 static int gionbana_gfxrom;
20 static int gionbana_dispflag;
21 static int gionbana_flipscreen;
22 static int gionbana_flipx, gionbana_flipy;
23 static int gionbana_paltblnum;
24 static int gionbana_screen_refresh;
25 static int gfxdraw_mode;
26 
27 static struct mame_bitmap *gionbana_tmpbitmap0, *gionbana_tmpbitmap1;
28 static unsigned char *gionbana_videoram0, *gionbana_videoram1;
29 static unsigned char *gionbana_palette;
30 static unsigned char *gionbana_paltbl;
31 
32 
33 static void gionbana_vramflip(int vram);
34 static void gionbana_gfxdraw(void);
35 
36 
37 /******************************************************************************
38 
39 
40 ******************************************************************************/
READ_HANDLER(gionbana_palette_r)41 READ_HANDLER( gionbana_palette_r )
42 {
43 	return gionbana_palette[offset];
44 }
45 
WRITE_HANDLER(gionbana_palette_w)46 WRITE_HANDLER( gionbana_palette_w )
47 {
48 	int r, g, b;
49 
50 	gionbana_palette[offset] = data;
51 
52 	if (!(offset & 1)) return;
53 
54 	offset &= 0x1fe;
55 
56 	r = ((gionbana_palette[offset + 0] & 0x0f) << 4);
57 	g = ((gionbana_palette[offset + 1] & 0xf0) << 0);
58 	b = ((gionbana_palette[offset + 1] & 0x0f) << 4);
59 
60 	r = (r | (r >> 4));
61 	g = (g | (g >> 4));
62 	b = (b | (b >> 4));
63 
64 	palette_set_color((offset >> 1), r, g, b);
65 }
66 
READ_HANDLER(maiko_palette_r)67 READ_HANDLER( maiko_palette_r )
68 {
69 	return gionbana_palette[offset];
70 }
71 
WRITE_HANDLER(maiko_palette_w)72 WRITE_HANDLER( maiko_palette_w )
73 {
74 	int r, g, b;
75 
76 	gionbana_palette[offset] = data;
77 
78 	if (!(offset & 0x100)) return;
79 
80 	offset &= 0x0ff;
81 
82 	r = ((gionbana_palette[offset + 0x000] & 0x0f) << 4);
83 	g = ((gionbana_palette[offset + 0x000] & 0xf0) << 0);
84 	b = ((gionbana_palette[offset + 0x100] & 0x0f) << 4);
85 
86 	r = (r | (r >> 4));
87 	g = (g | (g >> 4));
88 	b = (b | (b >> 4));
89 
90 	palette_set_color((offset & 0x0ff), r, g, b);
91 }
92 
93 /******************************************************************************
94 
95 
96 ******************************************************************************/
gionbana_radrx_w(int data)97 void gionbana_radrx_w(int data)
98 {
99 	gionbana_radrx = data;
100 }
101 
gionbana_radry_w(int data)102 void gionbana_radry_w(int data)
103 {
104 	gionbana_radry = data;
105 }
106 
gionbana_sizex_w(int data)107 void gionbana_sizex_w(int data)
108 {
109 	gionbana_sizex = data;
110 }
111 
gionbana_sizey_w(int data)112 void gionbana_sizey_w(int data)
113 {
114 	gionbana_sizey = data;
115 
116 	gionbana_gfxdraw();
117 }
118 
gionbana_gfxflag_w(int data)119 void gionbana_gfxflag_w(int data)
120 {
121 	static int gionbana_flipscreen_old = -1;
122 
123 	gionbana_flipx = (data & 0x01) ? 1 : 0;
124 	gionbana_flipy = (data & 0x02) ? 1 : 0;
125 	gionbana_flipscreen = (data & 0x04) ? 1 : 0;
126 	gionbana_dispflag = (data & 0x08) ? 0 : 1;
127 
128 	if (gionbana_flipscreen != gionbana_flipscreen_old)
129 	{
130 		if (gfxdraw_mode) gionbana_vramflip(1);
131 		gionbana_vramflip(0);
132 		gionbana_screen_refresh = 1;
133 		gionbana_flipscreen_old = gionbana_flipscreen;
134 	}
135 }
136 
gionbana_drawx_w(int data)137 void gionbana_drawx_w(int data)
138 {
139 	gionbana_drawx = (data ^ 0xff) & 0xff;
140 }
141 
gionbana_drawy_w(int data)142 void gionbana_drawy_w(int data)
143 {
144 	gionbana_drawy = (data ^ 0xff) & 0xff;
145 }
146 
gionbana_scrolly_w(int data)147 void gionbana_scrolly_w(int data)
148 {
149 	if (gionbana_flipscreen) gionbana_scrolly1 = -2;
150 	else gionbana_scrolly1 = 0;
151 
152 	if (gionbana_flipscreen) gionbana_scrolly2 = (data ^ 0xff) & 0xff;
153 	else gionbana_scrolly2 = (data - 1) & 0xff;
154 }
155 
gionbana_vramsel_w(int data)156 void gionbana_vramsel_w(int data)
157 {
158 	/* protection - not sure about this */
159 	nb1413m3_sndromregion = (data & 0x20) ? REGION_USER1 : REGION_SOUND1;
160 
161 	gionbana_vram = data;
162 }
163 
gionbana_romsel_w(int data)164 void gionbana_romsel_w(int data)
165 {
166 	gionbana_gfxrom = (data & 0x0f);
167 
168 	if ((0x20000 * gionbana_gfxrom) > (memory_region_length(REGION_GFX1) - 1))
169 	{
170 #ifdef MAME_DEBUG
171 		usrintf_showmessage("GFXROM BANK OVER!!");
172 #endif
173 		gionbana_gfxrom &= (memory_region_length(REGION_GFX1)/0x20000 - 1);
174 	}
175 }
176 
gionbana_paltblnum_w(int data)177 void gionbana_paltblnum_w(int data)
178 {
179 	gionbana_paltblnum = data;
180 }
181 
READ_HANDLER(gionbana_paltbl_r)182 READ_HANDLER( gionbana_paltbl_r )
183 {
184 	return gionbana_paltbl[offset];
185 }
186 
WRITE_HANDLER(gionbana_paltbl_w)187 WRITE_HANDLER( gionbana_paltbl_w )
188 {
189 	gionbana_paltbl[((gionbana_paltblnum & 0x7f) * 0x10) + (offset & 0x0f)] = data;
190 }
191 
192 /******************************************************************************
193 
194 
195 ******************************************************************************/
gionbana_vramflip(int vram)196 void gionbana_vramflip(int vram)
197 {
198 	int x, y;
199 	unsigned char color1, color2;
200 	unsigned char *vidram;
201 
202 	vidram = vram ? gionbana_videoram1 : gionbana_videoram0;
203 
204 	for (y = 0; y < (Machine->drv->screen_height / 2); y++)
205 	{
206 		for (x = 0; x < Machine->drv->screen_width; x++)
207 		{
208 			color1 = vidram[(y * Machine->drv->screen_width) + x];
209 			color2 = vidram[((y ^ 0xff) * Machine->drv->screen_width) + (x ^ 0x1ff)];
210 			vidram[(y * Machine->drv->screen_width) + x] = color2;
211 			vidram[((y ^ 0xff) * Machine->drv->screen_width) + (x ^ 0x1ff)] = color1;
212 		}
213 	}
214 }
215 
gionbana_gfxdraw(void)216 static void gionbana_gfxdraw(void)
217 {
218 	unsigned char *GFX = memory_region(REGION_GFX1);
219 
220 	int x, y;
221 	int dx1, dx2, dy1, dy2;
222 	int startx, starty;
223 	int sizex, sizey;
224 	int skipx, skipy;
225 	int ctrx, ctry;
226 	int tflag1, tflag2;
227 	unsigned char color, color1, color2;
228 	unsigned char drawcolor1, drawcolor2;
229 	int gfxaddr;
230 
231 	if (gionbana_flipx)
232 	{
233 		gionbana_drawx -= (gionbana_sizex << 1);
234 		startx = gionbana_sizex;
235 		sizex = ((gionbana_sizex ^ 0xff) + 1);
236 		skipx = -1;
237 	}
238 	else
239 	{
240 		gionbana_drawx = (gionbana_drawx - gionbana_sizex);
241 		startx = 0;
242 		sizex = (gionbana_sizex + 1);
243 		skipx = 1;
244 	}
245 
246 	if (gionbana_flipy)
247 	{
248 		gionbana_drawy -= ((gionbana_sizey << 1) + 1);
249 		starty = gionbana_sizey;
250 		sizey = ((gionbana_sizey ^ 0xff) + 1);
251 		skipy = -1;
252 	}
253 	else
254 	{
255 		gionbana_drawy = (gionbana_drawy - gionbana_sizey - 1);
256 		starty = 0;
257 		sizey = (gionbana_sizey + 1);
258 		skipy = 1;
259 	}
260 
261 	Machine->pens[0xff] = 0;	/* palette_transparent_pen */
262 
263 	gfxaddr = ((gionbana_gfxrom << 17) + (gionbana_radry << 9) + (gionbana_radrx << 1));
264 
265 	for (y = starty, ctry = sizey; ctry > 0; y += skipy, ctry--)
266 	{
267 		for (x = startx, ctrx = sizex; ctrx > 0; x += skipx, ctrx--)
268 		{
269 			if ((gfxaddr > (memory_region_length(REGION_GFX1) - 1)))
270 			{
271 #ifdef MAME_DEBUG
272 				usrintf_showmessage("GFXROM ADDRESS OVER!!");
273 #endif
274 				gfxaddr &= (memory_region_length(REGION_GFX1) - 1);
275 			}
276 
277 			color = GFX[gfxaddr++];
278 
279 			if (gionbana_flipscreen)
280 			{
281 				dx1 = (((((gionbana_drawx + x) * 2) + 0) ^ 0x1ff) & 0x1ff);
282 				dx2 = (((((gionbana_drawx + x) * 2) + 1) ^ 0x1ff) & 0x1ff);
283 				dy1 = (((gionbana_drawy + y) ^ 0xff) & 0xff);
284 				dy2 = (((gionbana_drawy + y + (gionbana_scrolly2 & 0xff) + 2) ^ 0xff) & 0xff);
285 			}
286 			else
287 			{
288 				dx1 = ((((gionbana_drawx + x) * 2) + 0) & 0x1ff);
289 				dx2 = ((((gionbana_drawx + x) * 2) + 1) & 0x1ff);
290 				dy1 = ((gionbana_drawy + y) & 0xff);
291 				dy2 = ((gionbana_drawy + y + (-gionbana_scrolly2 & 0xff)) & 0xff);
292 			}
293 
294 			if (gionbana_flipx)
295 			{
296 				// flip
297 				color1 = (color & 0xf0) >> 4;
298 				color2 = (color & 0x0f) >> 0;
299 			}
300 			else
301 			{
302 				// normal
303 				color1 = (color & 0x0f) >> 0;
304 				color2 = (color & 0xf0) >> 4;
305 			}
306 
307 			drawcolor1 = gionbana_paltbl[((gionbana_paltblnum & 0x7f) << 4) + color1];
308 			drawcolor2 = gionbana_paltbl[((gionbana_paltblnum & 0x7f) << 4) + color2];
309 
310 			if (gfxdraw_mode)
311 			{
312 				if (gionbana_vram & 0x01)
313 				{
314 					tflag1 = (drawcolor1 != 0xff) ? 1 : 0;
315 					tflag2 = (drawcolor2 != 0xff) ? 1 : 0;
316 				}
317 				else
318 				{
319 					if (gionbana_vram & 0x08)
320 					{
321 						tflag1 = (drawcolor1 != 0xff) ? 1 : 0;
322 						tflag2 = (drawcolor2 != 0xff) ? 1 : 0;
323 					}
324 					else
325 					{
326 						tflag1 = tflag2 = 1;
327 					}
328 
329 					if (drawcolor1 == 0x7f) drawcolor1 = 0xff;
330 					if (drawcolor2 == 0x7f) drawcolor2 = 0xff;
331 				}
332 			}
333 			else
334 			{
335 				tflag1 = (drawcolor1 != 0xff) ? 1 : 0;
336 				tflag2 = (drawcolor2 != 0xff) ? 1 : 0;
337 				gionbana_vram = 0x02;
338 			}
339 
340 			nb1413m3_busyctr++;
341 
342 			if (gfxdraw_mode)
343 			{
344 				if (gionbana_vram & 0x01)
345 				{
346 					if (tflag1)
347 					{
348 						gionbana_videoram0[(dy1 * Machine->drv->screen_width) + dx1] = drawcolor1;
349 						plot_pixel(gionbana_tmpbitmap0, dx1, dy1, Machine->pens[drawcolor1]);
350 					}
351 					if (tflag2)
352 					{
353 						gionbana_videoram0[(dy1 * Machine->drv->screen_width) + dx2] = drawcolor2;
354 						plot_pixel(gionbana_tmpbitmap0, dx2, dy1, Machine->pens[drawcolor2]);
355 					}
356 				}
357 				if (gionbana_vram & 0x02)
358 				{
359 					if (tflag1)
360 					{
361 						gionbana_videoram1[(dy2 * Machine->drv->screen_width) + dx1] = drawcolor1;
362 						plot_pixel(gionbana_tmpbitmap1, dx1, dy2, Machine->pens[drawcolor1]);
363 					}
364 					if (tflag2)
365 					{
366 						gionbana_videoram1[(dy2 * Machine->drv->screen_width) + dx2] = drawcolor2;
367 						plot_pixel(gionbana_tmpbitmap1, dx2, dy2, Machine->pens[drawcolor2]);
368 					}
369 				}
370 			}
371 			else
372 			{
373 				if (tflag1)
374 				{
375 					gionbana_videoram0[(dy2 * Machine->drv->screen_width) + dx1] = drawcolor1;
376 					plot_pixel(gionbana_tmpbitmap0, dx1, dy2, Machine->pens[drawcolor1]);
377 				}
378 				if (tflag2)
379 				{
380 					gionbana_videoram0[(dy2 * Machine->drv->screen_width) + dx2] = drawcolor2;
381 					plot_pixel(gionbana_tmpbitmap0, dx2, dy2, Machine->pens[drawcolor2]);
382 				}
383 			}
384 		}
385 	}
386 
387 	nb1413m3_busyflag = (nb1413m3_busyctr > 4650) ? 0 : 1;
388 }
389 
390 /******************************************************************************
391 
392 
393 ******************************************************************************/
VIDEO_START(gionbana)394 VIDEO_START( gionbana )
395 {
396 	if ((gionbana_tmpbitmap0 = auto_bitmap_alloc(Machine->drv->screen_width, Machine->drv->screen_height)) == 0) return 1;
397 	if ((gionbana_tmpbitmap1 = auto_bitmap_alloc(Machine->drv->screen_width, Machine->drv->screen_height)) == 0) return 1;
398 	if ((gionbana_videoram0 = auto_malloc(Machine->drv->screen_width * Machine->drv->screen_height * sizeof(char))) == 0) return 1;
399 	if ((gionbana_videoram1 = auto_malloc(Machine->drv->screen_width * Machine->drv->screen_height * sizeof(char))) == 0) return 1;
400 	if ((gionbana_palette = auto_malloc(0x200 * sizeof(char))) == 0) return 1;
401 	if ((gionbana_paltbl = auto_malloc(0x800 * sizeof(char))) == 0) return 1;
402 	memset(gionbana_videoram0, 0x00, (Machine->drv->screen_width * Machine->drv->screen_height * sizeof(char)));
403 	memset(gionbana_videoram1, 0x00, (Machine->drv->screen_width * Machine->drv->screen_height * sizeof(char)));
404 	gfxdraw_mode = 1;
405 	return 0;
406 }
407 
VIDEO_START(hanamomo)408 VIDEO_START( hanamomo )
409 {
410 	if ((gionbana_tmpbitmap0 = auto_bitmap_alloc(Machine->drv->screen_width, Machine->drv->screen_height)) == 0) return 1;
411 	if ((gionbana_videoram0 = auto_malloc(Machine->drv->screen_width * Machine->drv->screen_height * sizeof(char))) == 0) return 1;
412 	if ((gionbana_palette = auto_malloc(0x200 * sizeof(char))) == 0) return 1;
413 	if ((gionbana_paltbl = auto_malloc(0x800 * sizeof(char))) == 0) return 1;
414 	memset(gionbana_videoram0, 0x00, (Machine->drv->screen_width * Machine->drv->screen_height * sizeof(char)));
415 	gfxdraw_mode = 0;
416 	return 0;
417 }
418 
419 /******************************************************************************
420 
421 
422 ******************************************************************************/
VIDEO_UPDATE(gionbana)423 VIDEO_UPDATE( gionbana )
424 {
425 	int x, y;
426 	unsigned char color;
427 
428 	if (get_vh_global_attribute_changed() || gionbana_screen_refresh)
429 	{
430 		gionbana_screen_refresh = 0;
431 
432 		Machine->pens[0xff] = 0;	/* palette_transparent_pen */
433 
434 		for (y = 0; y < Machine->drv->screen_height; y++)
435 		{
436 			for (x = 0; x < Machine->drv->screen_width; x++)
437 			{
438 				color = gionbana_videoram0[(y * Machine->drv->screen_width) + x];
439 				plot_pixel(gionbana_tmpbitmap0, x, y, Machine->pens[color]);
440 			}
441 		}
442 		if (gfxdraw_mode)
443 		{
444 			for (y = 0; y < Machine->drv->screen_height; y++)
445 			{
446 				for (x = 0; x < Machine->drv->screen_width; x++)
447 				{
448 					color = gionbana_videoram1[(y * Machine->drv->screen_width) + x];
449 					plot_pixel(gionbana_tmpbitmap1, x, y, Machine->pens[color]);
450 				}
451 			}
452 		}
453 	}
454 
455 	if (gionbana_dispflag)
456 	{
457 		if (gfxdraw_mode)
458 		{
459 			copyscrollbitmap(bitmap, gionbana_tmpbitmap0, 0, 0, 1, &gionbana_scrolly1, &Machine->visible_area, TRANSPARENCY_NONE, 0);
460 			copyscrollbitmap(bitmap, gionbana_tmpbitmap1, 0, 0, 1, &gionbana_scrolly2, &Machine->visible_area, TRANSPARENCY_PEN, Machine->pens[0xff]);
461 		}
462 		else
463 		{
464 			copyscrollbitmap(bitmap, gionbana_tmpbitmap0, 0, 0, 1, &gionbana_scrolly2, &Machine->visible_area, TRANSPARENCY_NONE, 0);
465 		}
466 	}
467 	else
468 	{
469 		fillbitmap(bitmap, Machine->pens[0xff], 0);
470 	}
471 }
472