1 /***************************************************************************
2 
3   vidhrdw.c
4 
5   Functions to emulate the video hardware of the machine.
6 
7 ***************************************************************************/
8 
9 #include "driver.h"
10 #include "vidhrdw/generic.h"
11 #include "artwork.h"
12 
13 static int use_tmpbitmap;
14 static data_t screen_red;
15 static int screen_red_enabled;		/* 1 for games that can turn the screen red */
16 static data_t color_map_select;
17 static int background_color;
18 
19 static int overlay_type;	/* 0=none, 1=geometric, 2=file */
20 static const void *init_overlay;
21 
22 static mem_write_handler videoram_w_p;
23 static void (*vh_screenrefresh_p)(struct osd_bitmap *bitmap,int full_refresh);
24 static void (*plot_pixel_p)(int x, int y, int col);
25 
26 static WRITE_HANDLER( bw_videoram_w );
27 static WRITE_HANDLER( schaser_videoram_w );
28 static WRITE_HANDLER( lupin3_videoram_w );
29 static WRITE_HANDLER( polaris_videoram_w );
30 static WRITE_HANDLER( invadpt2_videoram_w );
31 static WRITE_HANDLER( astinvad_videoram_w );
32 static WRITE_HANDLER( spaceint_videoram_w );
33 static WRITE_HANDLER( helifire_videoram_w );
34 
35 static void vh_screenrefresh(struct osd_bitmap *bitmap,int full_refresh);
36 static void seawolf_vh_screenrefresh(struct osd_bitmap *bitmap,int full_refresh);
37 static void blueshrk_vh_screenrefresh(struct osd_bitmap *bitmap,int full_refresh);
38 static void desertgu_vh_screenrefresh(struct osd_bitmap *bitmap,int full_refresh);
39 static void phantom2_vh_screenrefresh(struct osd_bitmap *bitmap,int full_refresh);
40 
41 static void plot_pixel_8080 (int x, int y, int col);
42 static void plot_pixel_8080_tmpbitmap (int x, int y, int col);
43 
44 /* smoothed pure colors, overlays are not so contrasted */
45 
46 #define RED				0xff,0x20,0x20,OVERLAY_DEFAULT_OPACITY
47 #define GREEN 			0x20,0xff,0x20,OVERLAY_DEFAULT_OPACITY
48 #define YELLOW			0xff,0xff,0x20,OVERLAY_DEFAULT_OPACITY
49 #define CYAN			0x20,0xff,0xff,OVERLAY_DEFAULT_OPACITY
50 
51 #define	END  {{ -1, -1, -1, -1}, 0,0,0,0}
52 
53 
54 static const struct artwork_element invaders_overlay[]=
55 {
56 	{{  16,  71,   0, 255}, GREEN },
57 	{{   0,  15,  16, 133}, GREEN },
58 	{{ 192, 223,   0, 255}, RED   },
59 	END
60 };
61 
62 //static const struct artwork_element invdpt2m_overlay[]=
63 //{
64 //	{{  16,  71,   0, 255}, GREEN  },
65 //	{{   0,  15,  16, 133}, GREEN  },
66 //	{{  72, 191,   0, 255}, YELLOW },
67 //	{{ 192, 223,   0, 255}, RED    },
68 //	END
69 //};
70 
71 static const struct artwork_element invrvnge_overlay[]=
72 {
73 	{{   0,  71,   0, 255}, GREEN },
74 	{{ 192, 223,   0, 255}, RED   },
75 	END
76 };
77 
78 static const struct artwork_element invad2ct_overlay[]=
79 {
80 	{{	 0,  47,   0, 255}, YELLOW },
81 	{{	25,  70,   0, 255}, GREEN  },
82 	{{	48, 139,   0, 255}, CYAN   },
83 	{{ 117, 185,   0, 255}, GREEN  },
84 	{{ 163, 231,   0, 255}, YELLOW },
85 	{{ 209, 255,   0, 255}, RED    },
86 	END
87 };
88 
89 
init_8080bw(void)90 void init_8080bw(void)
91 {
92 	videoram_w_p = bw_videoram_w;
93 	vh_screenrefresh_p = vh_screenrefresh;
94 	use_tmpbitmap = 0;
95 	screen_red = 0;
96 	screen_red_enabled = 0;
97 	overlay_type = 0;
98 	color_map_select = 0;
99 	flip_screen_w(0,0);
100 }
101 
init_invaders(void)102 void init_invaders(void)
103 {
104 	init_8080bw();
105 	init_overlay = invaders_overlay;
106 	overlay_type = 1;
107 }
108 
init_invaddlx(void)109 void init_invaddlx(void)
110 {
111 	init_8080bw();
112 	//init_overlay = invdpt2m_overlay;
113 	//overlay_type = 1;
114 }
115 
init_invrvnge(void)116 void init_invrvnge(void)
117 {
118 	init_8080bw();
119 	init_overlay = invrvnge_overlay;
120 	overlay_type = 1;
121 }
122 
init_invad2ct(void)123 void init_invad2ct(void)
124 {
125 	init_8080bw();
126 	init_overlay = invad2ct_overlay;
127 	overlay_type = 1;
128 }
129 
init_schaser(void)130 void init_schaser(void)
131 {
132 	init_8080bw();
133 	videoram_w_p = schaser_videoram_w;
134 	background_color = 2;	/* blue */
135 }
136 
init_rollingc(void)137 void init_rollingc(void)
138 {
139 	init_8080bw();
140 	videoram_w_p = schaser_videoram_w;
141 	background_color = 0;	/* black */
142 }
143 
init_helifire(void)144 void init_helifire(void)
145 {
146 	init_8080bw();
147 	videoram_w_p = helifire_videoram_w;
148 }
149 
init_polaris(void)150 void init_polaris(void)
151 {
152 	init_8080bw();
153 	videoram_w_p = polaris_videoram_w;
154 }
155 
init_lupin3(void)156 void init_lupin3(void)
157 {
158 	init_8080bw();
159 	videoram_w_p = lupin3_videoram_w;
160 	background_color = 0;	/* black */
161 }
162 
init_invadpt2(void)163 void init_invadpt2(void)
164 {
165 	init_8080bw();
166 	videoram_w_p = invadpt2_videoram_w;
167 	screen_red_enabled = 1;
168 }
169 
init_seawolf(void)170 void init_seawolf(void)
171 {
172 	init_8080bw();
173 	vh_screenrefresh_p = seawolf_vh_screenrefresh;
174 	use_tmpbitmap = 1;
175 }
176 
init_blueshrk(void)177 void init_blueshrk(void)
178 {
179 	init_8080bw();
180 	vh_screenrefresh_p = blueshrk_vh_screenrefresh;
181 	use_tmpbitmap = 1;
182 }
183 
init_desertgu(void)184 void init_desertgu(void)
185 {
186 	init_8080bw();
187 	vh_screenrefresh_p = desertgu_vh_screenrefresh;
188 	use_tmpbitmap = 1;
189 }
190 
init_astinvad(void)191 void init_astinvad(void)
192 {
193 	init_8080bw();
194 	videoram_w_p = astinvad_videoram_w;
195 	screen_red_enabled = 1;
196 }
197 
init_spaceint(void)198 void init_spaceint(void)
199 {
200 	init_8080bw();
201 	videoram_w_p = spaceint_videoram_w;
202 }
203 
init_spcenctr(void)204 void init_spcenctr(void)
205 {
206 	extern struct GameDriver driver_spcenctr;
207 
208 	init_8080bw();
209 	init_overlay = driver_spcenctr.name;
210 	overlay_type = 2;
211 }
212 
init_phantom2(void)213 void init_phantom2(void)
214 {
215 	init_8080bw();
216 	vh_screenrefresh_p = phantom2_vh_screenrefresh;
217 	use_tmpbitmap = 1;
218 }
219 
220 
invaders_vh_start(void)221 int invaders_vh_start(void)
222 {
223 	/* create overlay if one of was specified in init_X */
224 	if (overlay_type)
225 	{
226 		int start_pen;
227 		int max_pens;
228 
229 
230 		start_pen = 2;
231 		max_pens = Machine->drv->total_colors-start_pen;
232 
233 		if (overlay_type == 1)
234 			overlay_create((const struct artwork_element *)init_overlay, start_pen, max_pens);
235 		else
236 			overlay_load((const char *)init_overlay, start_pen, max_pens);
237 	}
238 
239 	if (use_tmpbitmap && (generic_bitmapped_vh_start() != 0))
240 		return 1;
241 
242 	if (use_tmpbitmap)
243 	{
244 		plot_pixel_p = plot_pixel_8080_tmpbitmap;
245 	}
246 	else
247 	{
248 		plot_pixel_p = plot_pixel_8080;
249 	}
250 
251 	/* make sure that the screen matches the videoram, this fixes invad2ct */
252 	//schedule_full_refresh();
253 
254 	return 0;
255 }
256 
257 
invaders_vh_stop(void)258 void invaders_vh_stop(void)
259 {
260 	if (use_tmpbitmap)  generic_bitmapped_vh_stop();
261 }
262 
263 
invaders_flip_screen_w(int data)264 void invaders_flip_screen_w(int data)
265 {
266 	set_vh_global_attribute(&color_map_select, data);
267 
268 	if (input_port_3_r(0) & 0x01)
269 	{
270 		flip_screen_w(0, data);
271 	}
272 }
273 
274 
invaders_screen_red_w(int data)275 void invaders_screen_red_w(int data)
276 {
277 	if (screen_red_enabled)
278 	{
279 		set_vh_global_attribute(&screen_red, data);
280 	}
281 }
282 
283 
plot_pixel_8080(int x,int y,int col)284 static void plot_pixel_8080 (int x, int y, int col)
285 {
286 	if (flip_screen)
287 	{
288 		x = 255-x;
289 		y = 223-y;
290 	}
291 
292 	plot_pixel(Machine->scrbitmap,x,y,Machine->pens[col]);
293 }
294 
plot_pixel_8080_tmpbitmap(int x,int y,int col)295 static void plot_pixel_8080_tmpbitmap (int x, int y, int col)
296 {
297 	if (flip_screen)
298 	{
299 		x = 255-x;
300 		y = 223-y;
301 	}
302 
303 	plot_pixel(tmpbitmap,x,y,Machine->pens[col]);
304 }
305 
plot_byte(int x,int y,int data,int fore_color,int back_color)306 static INLINE void plot_byte(int x, int y, int data, int fore_color, int back_color)
307 {
308 	int i;
309 
310 	for (i = 0; i < 8; i++)
311 	{
312 		plot_pixel_p (x, y, (data & 0x01) ? fore_color : back_color);
313 
314 		x++;
315 		data >>= 1;
316 	}
317 }
318 
319 
WRITE_HANDLER(invaders_videoram_w)320 WRITE_HANDLER( invaders_videoram_w )
321 {
322 	videoram_w_p(offset, data);
323 }
324 
325 
WRITE_HANDLER(bw_videoram_w)326 static WRITE_HANDLER( bw_videoram_w )
327 {
328 	int x,y;
329 
330 	videoram[offset] = data;
331 
332 	y = offset / 32;
333 	x = 8 * (offset % 32);
334 
335 	plot_byte(x, y, data, 1, 0);
336 }
337 
WRITE_HANDLER(schaser_videoram_w)338 static WRITE_HANDLER( schaser_videoram_w )
339 {
340 	int x,y,col;
341 
342 	videoram[offset] = data;
343 
344 	y = offset / 32;
345 	x = 8 * (offset % 32);
346 
347 	col = colorram[offset & 0x1f1f] & 0x07;
348 
349 	plot_byte(x, y, data, col, background_color);
350 }
351 
WRITE_HANDLER(lupin3_videoram_w)352 static WRITE_HANDLER( lupin3_videoram_w )
353 {
354 	int x,y,col;
355 
356 	videoram[offset] = data;
357 
358 	y = offset / 32;
359 	x = 8 * (offset % 32);
360 
361 	col = ~colorram[offset & 0x1f1f] & 0x07;
362 
363 	plot_byte(x, y, data, col, background_color);
364 }
365 
WRITE_HANDLER(polaris_videoram_w)366 static WRITE_HANDLER( polaris_videoram_w )
367 {
368 	int x,y,back_color,foreground_color;
369 
370 	videoram[offset] = data;
371 
372 	y = offset / 32;
373 	x = 8 * (offset % 32);
374 
375 	/* for the background color, bit 0 if the map PROM is connected to blue gun.
376 	   red is 0 */
377 
378 	back_color = (memory_region(REGION_PROMS)[(((y+32)/8)*32) + (x/8)] & 1) ? 6 : 4;
379 	foreground_color = ~colorram[offset & 0x1f1f] & 0x07;
380 
381 	plot_byte(x, y, data, foreground_color, back_color);
382 }
383 
WRITE_HANDLER(helifire_videoram_w)384 static WRITE_HANDLER( helifire_videoram_w )
385 {
386 	int x,y,back_color,foreground_color;
387 
388 	videoram[offset] = data;
389 
390 	y = offset / 32;
391 	x = 8 * (offset % 32);
392 
393 	back_color = 0;
394 	foreground_color = colorram[offset] & 0x07;
395 
396 	if (x < 0x78)
397 	{
398 		back_color = 4;	/* blue */
399 	}
400 
401 	plot_byte(x, y, data, foreground_color, back_color);
402 }
403 
404 
WRITE_HANDLER(schaser_colorram_w)405 WRITE_HANDLER( schaser_colorram_w )
406 {
407 	int i;
408 
409 
410 	offset &= 0x1f1f;
411 
412 	colorram[offset] = data;
413 
414 	/* redraw region with (possibly) changed color */
415 	for (i = 0; i < 8; i++, offset += 0x20)
416 	{
417 		videoram_w_p(offset, videoram[offset]);
418 	}
419 }
420 
READ_HANDLER(schaser_colorram_r)421 READ_HANDLER( schaser_colorram_r )
422 {
423 	return colorram[offset & 0x1f1f];
424 }
425 
426 
WRITE_HANDLER(helifire_colorram_w)427 WRITE_HANDLER( helifire_colorram_w )
428 {
429 	colorram[offset] = data;
430 
431 	/* redraw region with (possibly) changed color */
432 	videoram_w_p(offset, videoram[offset]);
433 }
434 
435 
436 /***************************************************************************
437 
438   Draw the game screen in the given osd_bitmap.
439   Do NOT call osd_update_display() from this function, it will be called by
440   the main emulation engine.
441 
442 ***************************************************************************/
invaders_vh_screenrefresh(struct osd_bitmap * bitmap,int full_refresh)443 void invaders_vh_screenrefresh(struct osd_bitmap *bitmap,int full_refresh)
444 {
445 	vh_screenrefresh_p(bitmap, full_refresh);
446 }
447 
448 
vh_screenrefresh(struct osd_bitmap * bitmap,int full_refresh)449 static void vh_screenrefresh(struct osd_bitmap *bitmap,int full_refresh)
450 {
451 	if (palette_recalc() || full_refresh)
452 	{
453 		int offs;
454 
455 		for (offs = 0;offs < videoram_size;offs++)
456 			videoram_w_p(offs, videoram[offs]);
457 	}
458 
459 
460 	if (use_tmpbitmap)
461 		copybitmap(bitmap,tmpbitmap,0,0,0,0,&Machine->visible_area,TRANSPARENCY_NONE,0);
462 }
463 
464 
draw_sight(int x_center,int y_center)465 static void draw_sight(int x_center, int y_center)
466 {
467 	int x,y;
468 
469 
470     if (x_center<2)   x_center=2;
471     if (x_center>253) x_center=253;
472 
473     if (y_center<2)   y_center=2;
474     if (y_center>253) y_center=253;
475 
476 	for(y = y_center-10; y < y_center+11; y++)
477 		if((y >= 0) && (y < 256))
478 			plot_pixel_8080(x_center,y,1);
479 
480 	for(x = x_center-20; x < x_center+21; x++)
481 		if((x >= 0) && (x < 256))
482 			plot_pixel_8080(x,y_center,1);
483 }
484 
485 
seawolf_vh_screenrefresh(struct osd_bitmap * bitmap,int full_refresh)486 static void seawolf_vh_screenrefresh(struct osd_bitmap *bitmap,int full_refresh)
487 {
488 	/* update the bitmap (and erase old cross) */
489 	vh_screenrefresh(bitmap, full_refresh);
490 
491     draw_sight(((input_port_0_r(0) & 0x1f) * 8) + 4, 31);
492 }
493 
blueshrk_vh_screenrefresh(struct osd_bitmap * bitmap,int full_refresh)494 static void blueshrk_vh_screenrefresh(struct osd_bitmap *bitmap,int full_refresh)
495 {
496 	/* update the bitmap (and erase old cross) */
497 	vh_screenrefresh(bitmap, full_refresh);
498 
499     draw_sight(((input_port_0_r(0) & 0x7f) * 2) - 12, 31);
500 }
501 
desertgu_vh_screenrefresh(struct osd_bitmap * bitmap,int full_refresh)502 static void desertgu_vh_screenrefresh(struct osd_bitmap *bitmap,int full_refresh)
503 {
504 	/* update the bitmap (and erase old cross) */
505 	vh_screenrefresh(bitmap, full_refresh);
506 
507 	draw_sight(((input_port_0_r(0) & 0x7f) * 2) - 30,
508 			   ((input_port_2_r(0) & 0x7f) * 2) - 30);
509 }
510 
phantom2_vh_screenrefresh(struct osd_bitmap * bitmap,int full_refresh)511 static void phantom2_vh_screenrefresh(struct osd_bitmap *bitmap,int full_refresh)
512 {
513 	unsigned char *clouds;
514 	int x, y;
515 
516 
517 	/* update the bitmap */
518 	vh_screenrefresh(bitmap, full_refresh);
519 
520 
521 	/* draw the clouds */
522 	clouds = memory_region(REGION_PROMS);
523 
524 	for (y = 0; y < 128; y++)
525 	{
526 		unsigned char *offs = &memory_region(REGION_PROMS)[y * 0x10];
527 
528 		for (x = 0; x < 128; x++)
529 		{
530 			if (offs[x >> 3] & (1 << (x & 0x07)))
531 			{
532 				plot_pixel_8080(x*2,   y*2,   1);
533 				plot_pixel_8080(x*2+1, y*2,   1);
534 				plot_pixel_8080(x*2,   y*2+1, 1);
535 				plot_pixel_8080(x*2+1, y*2+1, 1);
536 			}
537 		}
538 	}
539 }
540 
541 
invadpt2_vh_convert_color_prom(unsigned char * palette,unsigned short * colortable,const unsigned char * color_prom)542 void invadpt2_vh_convert_color_prom(unsigned char *palette, unsigned short *colortable,const unsigned char *color_prom)
543 {
544 	int i;
545 
546 
547 	for (i = 0;i < Machine->drv->total_colors;i++)
548 	{
549 		/* this bit arrangment is a little unusual but are confirmed by screen shots */
550 
551 		*(palette++) = 0xff * ((i >> 0) & 1);
552 		*(palette++) = 0xff * ((i >> 2) & 1);
553 		*(palette++) = 0xff * ((i >> 1) & 1);
554 	}
555 }
556 
helifire_vh_convert_color_prom(unsigned char * palette,unsigned short * colortable,const unsigned char * color_prom)557 void helifire_vh_convert_color_prom(unsigned char *palette, unsigned short *colortable,const unsigned char *color_prom)
558 {
559 	int i;
560 
561 
562 	for (i = 0;i < Machine->drv->total_colors;i++)
563 	{
564 		*(palette++) = 0xff * ((i >> 0) & 1);
565 		*(palette++) = 0xff * ((i >> 1) & 1);
566 		*(palette++) = 0xff * ((i >> 2) & 1);
567 	}
568 }
569 
570 
WRITE_HANDLER(invadpt2_videoram_w)571 static WRITE_HANDLER( invadpt2_videoram_w )
572 {
573 	int x,y,col;
574 
575 	videoram[offset] = data;
576 
577 	y = offset / 32;
578 	x = 8 * (offset % 32);
579 
580 	/* 32 x 32 colormap */
581 	if (!screen_red)
582 		col = memory_region(REGION_PROMS)[(color_map_select ? 0x400 : 0 ) + (((y+32)/8)*32) + (x/8)] & 7;
583 	else
584 		col = 1;	/* red */
585 
586 	plot_byte(x, y, data, col, 0);
587 }
588 
WRITE_HANDLER(astinvad_videoram_w)589 static WRITE_HANDLER( astinvad_videoram_w )
590 {
591 	int x,y,col;
592 
593 	videoram[offset] = data;
594 
595 	y = offset / 32;
596 	x = 8 * (offset % 32);
597 
598 	if (!screen_red)
599 	{
600 		if (flip_screen)
601 			col = memory_region(REGION_PROMS)[((y+32)/8)*32+(x/8)] >> 4;
602 		else
603 			col = memory_region(REGION_PROMS)[(31-y/8)*32+(31-x/8)] & 0x0f;
604 	}
605 	else
606 		col = 1; /* red */
607 
608 	plot_byte(x, y, data, col, 0);
609 }
610 
WRITE_HANDLER(spaceint_videoram_w)611 static WRITE_HANDLER( spaceint_videoram_w )
612 {
613 	int i,x,y,col;
614 
615 	videoram[offset] = data;
616 
617 	y = 8 * (offset / 256);
618 	x = offset % 256;
619 
620 	/* this is wrong */
621 	col = memory_region(REGION_PROMS)[(y/16)+16*((x+16)/32)];
622 
623 	for (i = 0; i < 8; i++)
624 	{
625 		plot_pixel_p(x, y, (data & 0x01) ? col : 0);
626 
627 		y++;
628 		data >>= 1;
629 	}
630 }
631